Esempio n. 1
0
    def _test_bad_assertion(self, idx=None, in_one_day=None):
        if idx is None:
            idx = random.choice(range(self.vusers))

        if in_one_day is None:
            in_one_day = int(time.time() + 60 * 60 * 24) * 1000
        email = "{uid}@{host}".format(uid=idx, host="mockmyid.com")
        # expired assertion
        expired = make_assertion(
                email=email,
                issuer=self.valid_domain,
                exp=int(time.time() - 60) * 1000,
                audience=self.audience,
                issuer_keypair=(None, MOCKMYID_PRIVATE_KEY))
        self._do_token_exchange(expired, 401)

        # wrong issuer
        wrong_issuer = make_assertion(email, exp=in_one_day,
                                        audience=self.audience)
        self._do_token_exchange(wrong_issuer, 401)

        # wrong email host
        email = "{uid}@{host}".format(uid=idx, host=self.invalid_domain)
        wrong_email_host = make_assertion(
                email, issuer=self.valid_domain,
                exp=in_one_day,
                audience=self.audience,
                issuer_keypair=(None, MOCKMYID_PRIVATE_KEY))
        self._do_token_exchange(wrong_email_host, 401)
Esempio n. 2
0
 def test_verification_of_untrusted_issuer(self):
     audience = "http://example.com"
     issuer = "moz.com"
     # Assertions for @moz.com addresses can come from moz.com
     assertion = make_assertion("*****@*****.**", audience, issuer=issuer)
     self.assertTrue(self.verifier.verify(assertion, audience))
     # But assertions for other addresses cannot (unless they delegated).
     assertion = make_assertion("*****@*****.**", audience, issuer=issuer)
     self.assertRaises(InvalidSignatureError, self.verifier.verify, assertion, audience)
Esempio n. 3
0
    def _generate_token(self):
        """Pick an identity, log in and generate the auth token."""
        uid = random.randint(1, 1000000)  # existing user
        # Use the tokenserver if configured, otherwise fake it ourselves.
        if self.token_server_url is None:
            self.logi("synthesizing token for uid %s" % (uid,))
            endpoint_node = random.choice(self.endpoint_nodes)
            req = Request.blank(endpoint_node)
            token, secret = self.auth_plugin.encode_mac_id(req, uid)
            endpoint_url = endpoint_node + "/%s/%s" % (VERSION, uid)
        else:
            email = "*****@*****.**" % (uid,)
            self.logi("requesting token for %s" % (email,))
            assertion = make_assertion(email, audience="persona.org",
                                       issuer="loadtest.local")
            token_url = self.token_server_url + "/1.0/aitc/1.0"
            self.addHeader("Authorization", "Browser-ID " + assertion)
            response = self.get(token_url)
            credentials = json.loads(response.body)
            token = credentials["id"].encode("ascii")
            secret = credentials["key"].encode("ascii")
            endpoint_url = credentials["api_endpoint"]

        self.logi("assigned endpoint_url %s" % (endpoint_url))
        return token, secret, endpoint_url
Esempio n. 4
0
 def test_verification_of_valid_dummy_assertion(self):
     audience = "http://example.com"
     assertion = make_assertion("*****@*****.**", audience)
     self.assertTrue(self.verifier.verify(assertion))
     self.assertTrue(self.verifier.verify(assertion, audience))
     self.assertRaises(AudienceMismatchError,
                       self.verifier.verify, assertion, "http://moz.com")
Esempio n. 5
0
 def test_verification_of_expired_dummy_assertion(self):
     audience = "http://example.com"
     now = (time.time() * 1000)
     assertion = make_assertion("*****@*****.**", audience, exp=now - 1)
     self.assertTrue(self.verifier.verify(assertion, now=now - 2))
     self.assertRaises(ExpiredSignatureError, self.verifier.verify,
                       assertion)
Esempio n. 6
0
def get_assertion(email, audience='*', hostname='browserid.org',
        bad_issuer_cert=False, bad_email_cert=False):
    """Creates a browserid assertion for the given email, audience and
    hostname.

    This function can also be used to create invalid assertions. This will be
    the case if you set the bad_issuer_cert or the bad_email cert arguments to
    True.
    """

    key = load_key(hostname)
    pub = key.rsa.pub()[1].decode('latin-1')

    kwargs = {
        'issuer_keypair': (pub, key),
        'email_keypair': (pub, key)
    }

    # We remove the issuer_keypair and email_keypair arguments, which will let
    # the underlying make_assertion function from browserid use its internal
    # test certificates, which are not the same as the one we use for the
    # tokenserver.

    if bad_issuer_cert:
        del kwargs['issuer_keypair']

    if bad_email_cert:
        del kwargs['email_keypair']

    return make_assertion(email, audience, **kwargs)
Esempio n. 7
0
 def test_single_token_exchange_new_user(self):
     uid = str(uuid.uuid1())
     email = "loadtest-{uid}@{host}".format(uid=uid, host=self.valid_domain)
     self._do_token_exchange(make_assertion(
         email=email,
         issuer=self.valid_domain,
         audience=self.audience,
         issuer_keypair=(None, MOCKMYID_PRIVATE_KEY)))
Esempio n. 8
0
 def test_single_token_exchange(self):
     uid = random.randint(1, 1000000)
     email = "user{uid}@{host}".format(uid=uid, host=self.valid_domain)
     self._do_token_exchange(make_assertion(
         email=email,
         issuer=self.valid_domain,
         audience=self.audience,
         issuer_keypair=(None, MOCKMYID_PRIVATE_KEY)))
Esempio n. 9
0
 def test_extraction_of_extra_claims(self):
     assertion = make_assertion("*****@*****.**", "http://e.com",
         idp_claims={"extra": "claim"},
         user_claims={"another": "claim"},
     )
     result = self.verifier.verify(assertion)
     self.assertEqual(result["status"], "okay")
     self.assertEqual(result["idpClaims"], {"extra": "claim"})
     self.assertEqual(result["userClaims"], {"another": "claim"})
Esempio n. 10
0
    def test_cache_eviction_during_write(self):
        certs = CertificatesManager(cache_timeout=0.1)
        verifier = LocalVerifier(["*"], certs=certs, warning=False)
        # Prime the cache by verifying an assertion.
        assertion1 = make_assertion("*****@*****.**", "", "1.com")
        self.assertTrue(verifier.verify(assertion1))
        self.assertEquals(len(certs.cache), 1)
        # Let that cached key expire
        time.sleep(0.1)
        # Now grab a different key; caching it should purge the expired key.
        assertion2 = make_assertion("*****@*****.**", "", "2.com")
        self.assertTrue(verifier.verify(assertion2))
        self.assertEquals(len(certs.cache), 1)
        # Check that only the second entry is in cache.

        with patched_key_fetching(exc=RuntimeError("key fetch disabled")):
            self.assertTrue(verifier.verify(assertion2))
            self.assertRaises(RuntimeError, verifier.verify, assertion1)
Esempio n. 11
0
    def test_audience_verification(self):

        # create an assertion with the audience set to http://persona.org for
        # the tests. This assertion is only valid for this audience.
        assertion = make_assertion("*****@*****.**", "http://persona.org")

        # we don't set any audience explicitely here
        verifier = LocalVerifier()

        # specifying the audience on verifier.verify uses it.
        self.assertRaises(AudienceMismatchError, verifier.verify, assertion,
                          audience="*.example.com")

        # if we change the audience to the expected one, the assertion is
        # considered valid
        self.assertTrue(verifier.verify(assertion, audience="persona.org"))

        # specifying the audience when creating the verifier AND when calling
        # verifier.verify.
        verifier = LocalVerifier(["*.example.com"])
        self.assertRaises(AudienceMismatchError, verifier.verify, assertion,
                          audience="*.example.com")

        # specifying a different audience at instanciation and at verification,
        # only the last one is used.
        self.assertTrue(verifier.verify(assertion, audience="persona.org"))

        # overwritting the audience with an invalid one (we are waiting for
        # persona.org but getting example.com) raises an error
        self.assertRaises(AudienceMismatchError, verifier.verify,
                          audience="persona.org",
                          assertion=make_assertion("*****@*****.**",
                                                   "http://example.com"))

        # the assertion is valid for http://persona.org; the verifier is
        # configured to accept this audience so it should validate
        verifier = LocalVerifier(["persona.org"])
        self.assertTrue(verifier.verify(assertion))

        # but if we ask explicitely for a different audience (the assertion is
        # not accepted, even if the instance is configured so)
        self.assertRaises(AudienceMismatchError, verifier.verify,
                          assertion, audience="example.com")
Esempio n. 12
0
    def test_cache_eviction_during_write(self):
        supportdocs = SupportDocumentManager(cache_timeout=0.1)
        verifier = LocalVerifier(["*"], supportdocs=supportdocs)
        # Prime the cache by verifying an assertion.
        assertion1 = make_assertion("*****@*****.**", "", "1.com")
        self.assertTrue(verifier.verify(assertion1))
        self.assertEquals(len(supportdocs.cache), 1)
        # Let that cached key expire
        time.sleep(0.1)
        # Now grab a different key; caching it should purge the expired key.
        assertion2 = make_assertion("*****@*****.**", "", "2.com")
        self.assertTrue(verifier.verify(assertion2))
        self.assertEquals(len(supportdocs.cache), 1)
        # Check that only the second entry is in cache.

        exc = RuntimeError("key fetch disabled")
        with patched_supportdoc_fetching(exc=exc):
            self.assertTrue(verifier.verify(assertion2))
            self.assertRaises(RuntimeError, verifier.verify, assertion1)
Esempio n. 13
0
 def _make_assertion(self, email, **kwds):
     if "audience" not in kwds:
         kwds["audience"] = self.audience
     if "exp" not in kwds:
         kwds["exp"] = int((time.time() + ONE_YEAR) * 1000)
     if "issuer" not in kwds:
         kwds["issuer"] = MOCKMYID_DOMAIN
     if "issuer_keypair" not in kwds:
         kwds["issuer_keypair"] = (None, MOCKMYID_PRIVATE_KEY)
     return make_assertion(email, **kwds)
Esempio n. 14
0
    def test_cache_eviction_based_on_size(self):
        certs = CertificatesManager(max_size=2)
        verifier = LocalVerifier(["*"], certs=certs, warning=False)
        # Prime the cache by verifying some assertions.
        assertion1 = make_assertion("*****@*****.**", "", "1.com")
        self.assertTrue(verifier.verify(assertion1))
        assertion2 = make_assertion("*****@*****.**", "", "2.com")
        self.assertTrue(verifier.verify(assertion2))
        self.assertEquals(len(certs.cache), 2)
        # Hitting a third host should evict the first public key.
        assertion3 = make_assertion("*****@*****.**", "", "3.com")
        self.assertTrue(verifier.verify(assertion3))
        self.assertEquals(len(certs.cache), 2)
        # Make it error out if re-fetching any keys

        with patched_key_fetching(exc=RuntimeError("key fetch disabled")):
            # It should have to re-fetch for 1, but not 2.
            self.assertTrue(verifier.verify(assertion2))
            self.assertRaises(RuntimeError, verifier.verify, assertion1)
 def test_verifier_rejects_unallowed_issuers(self):
     config = self._make_config({  # noqa; indentation below is non-standard
         "browserid.audiences":
             "https://testmytoken.com",
         "browserid.allowed_issuers":
             "accounts.firefox.com mockmyid.com",
     })
     verifier = config.registry.getUtility(IBrowserIdVerifier)
     assertion = make_assertion(email="*****@*****.**",
                                audience="https://testmytoken.com")
     mock_response = {
         "status": "okay",
         "principal": {
             "email": "*****@*****.**",
         },
         "audience": "https://testmytoken.com",
         "issuer": "login.persona.org",
     }
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
     mock_response["issuer"] = "mockmyid.com"
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         self.assertEquals(
             verifier.verify(assertion)["principal"]["email"],
             "*****@*****.**")
     mock_response["issuer"] = "accounts.firefox.com"
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         self.assertEquals(
             verifier.verify(assertion)["principal"]["email"],
             "*****@*****.**")
     mock_response["issuer"] = "mockmyid.org"
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
     mock_response["issuer"] = "http://mockmyid.com"
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
     mock_response["issuer"] = "mockmyid.co"
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
     mock_response["issuer"] = 42
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
     mock_response["issuer"] = None
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
     del mock_response["issuer"]
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
Esempio n. 16
0
    def test_cache_eviction_based_on_size(self):
        supportdocs = SupportDocumentManager(max_size=2)
        verifier = LocalVerifier(["*"], supportdocs=supportdocs)
        # Prime the cache by verifying some assertions.
        assertion1 = make_assertion("*****@*****.**", "", "1.com")
        self.assertTrue(verifier.verify(assertion1))
        assertion2 = make_assertion("*****@*****.**", "", "2.com")
        self.assertTrue(verifier.verify(assertion2))
        self.assertEquals(len(supportdocs.cache), 2)
        # Hitting a third host should evict the first public key.
        assertion3 = make_assertion("*****@*****.**", "", "3.com")
        self.assertTrue(verifier.verify(assertion3))
        self.assertEquals(len(supportdocs.cache), 2)
        # Make it error out if re-fetching any keys

        exc = RuntimeError("key fetch disabled")
        with patched_supportdoc_fetching(exc=exc):
            # It should have to re-fetch for 1, but not 2.
            self.assertTrue(verifier.verify(assertion2))
            self.assertRaises(RuntimeError, verifier.verify, assertion1)
Esempio n. 17
0
    def test_cache_eviction_based_on_size(self):
        supportdocs = SupportDocumentManager(max_size=2)
        verifier = LocalVerifier(["*"], supportdocs=supportdocs)
        # Prime the cache by verifying some assertions.
        assertion1 = make_assertion("*****@*****.**", "", "1.com")
        self.assertTrue(verifier.verify(assertion1))
        assertion2 = make_assertion("*****@*****.**", "", "2.com")
        self.assertTrue(verifier.verify(assertion2))
        self.assertEquals(len(supportdocs.cache), 2)
        # Hitting a third host should evict the first public key.
        assertion3 = make_assertion("*****@*****.**", "", "3.com")
        self.assertTrue(verifier.verify(assertion3))
        self.assertEquals(len(supportdocs.cache), 2)
        # Make it error out if re-fetching any keys

        exc = RuntimeError("key fetch disabled")
        with patched_supportdoc_fetching(exc=exc):
            # It should have to re-fetch for 1, but not 2.
            self.assertTrue(verifier.verify(assertion2))
            self.assertRaises(RuntimeError, verifier.verify, assertion1)
Esempio n. 18
0
 def test_extraction_of_extra_claims(self):
     assertion = make_assertion(
         "*****@*****.**",
         "http://e.com",
         idp_claims={"extra": "claim"},
         user_claims={"another": "claim"},
     )
     result = self.verifier.verify(assertion)
     self.assertEqual(result["status"], "okay")
     self.assertEqual(result["idpClaims"], {"extra": "claim"})
     self.assertEqual(result["userClaims"], {"another": "claim"})
Esempio n. 19
0
    def test_cache_eviction_during_write(self):
        supportdocs = SupportDocumentManager(cache_timeout=0.1)
        verifier = LocalVerifier(["*"], supportdocs=supportdocs,
                warning=False)
        # Prime the cache by verifying an assertion.
        assertion1 = make_assertion("*****@*****.**", "", "1.com")
        self.assertTrue(verifier.verify(assertion1))
        self.assertEquals(len(supportdocs.cache), 1)
        # Let that cached key expire
        time.sleep(0.1)
        # Now grab a different key; caching it should purge the expired key.
        assertion2 = make_assertion("*****@*****.**", "", "2.com")
        self.assertTrue(verifier.verify(assertion2))
        self.assertEquals(len(supportdocs.cache), 1)
        # Check that only the second entry is in cache.

        exc = RuntimeError("key fetch disabled")
        with patched_supportdoc_fetching(exc=exc):
            self.assertTrue(verifier.verify(assertion2))
            self.assertRaises(RuntimeError, verifier.verify, assertion1)
 def _make_assertion(self, email=None, audience=None, **kwds):
     if email is None:
         email = "user%d@%s" % (random.randint(0, 1000000), MOCKMYID_DOMAIN)
     if audience is None:
         audience = "https://secret.mozilla.com"
     if "exp" not in kwds:
         kwds["exp"] = int((time.time() + ONE_YEAR) * 1000)
     if "issuer" not in kwds:
         kwds["issuer"] = MOCKMYID_DOMAIN
     if "issuer_keypair" not in kwds:
         kwds["issuer_keypair"] = (None, MOCKMYID_PRIVATE_KEY)
     return make_assertion(email, audience, **kwds)
Esempio n. 21
0
 def test_token_exchange(self):
     # a valid browserid assertion should be taken by the server and turned
     # back into an authentication token which is valid for 30 minutes.
     # we want to test this for a number of users, with different
     # assertions.
     for idx in range(self.vusers):
         email = "{uid}@{host}".format(uid=idx, host=self.valid_domain)
         self._do_token_exchange(make_assertion(
             email=email,
             issuer=self.valid_domain,
             audience=self.audience,
             issuer_keypair=(None, MOCKMYID_PRIVATE_KEY)))
Esempio n. 22
0
 def test_audience_pattern_checking(self):
     verifier = LocalVerifier(["*.moz.com", "www.test.com"], warning=False)
     # Domains like *.moz.com should be valid audiences.
     # They will work with both the implicit patterns and explicit audience.
     assertion = make_assertion("*****@*****.**", "www.moz.com")
     self.assertTrue(verifier.verify(assertion))
     self.assertTrue(verifier.verify(assertion, "www.moz.com"))
     self.assertRaises(AudienceMismatchError,
                       verifier.verify, assertion, "www.test.com")
     # The specific domain www.test.com should be a valid audience.
     # It will work with both the implicit patterns and explicit audience.
     assertion = make_assertion("*****@*****.**", "www.test.com")
     self.assertTrue(verifier.verify(assertion))
     self.assertTrue(verifier.verify(assertion, "www.test.com"))
     self.assertRaises(AudienceMismatchError,
                       verifier.verify, assertion, "www.moz.com")
     # Domains not matching any patterns should not be valid audiences.
     # They will fail unless given as an explicit argument.
     assertion = make_assertion("*****@*****.**", "www.evil.com")
     self.assertRaises(AudienceMismatchError, verifier.verify, assertion)
     self.assertTrue(verifier.verify(assertion, "www.evil.com"))
Esempio n. 23
0
 def _make_assertion(self, email=None, audience=None, **kwds):
     if email is None:
         email = "user%d@%s" % (random.randint(0, 1000000), MOCKMYID_DOMAIN)
     if audience is None:
         audience = "https://secret.mozilla.com"
     if "exp" not in kwds:
         kwds["exp"] = int((time.time() + ONE_YEAR) * 1000)
     if "issuer" not in kwds:
         kwds["issuer"] = MOCKMYID_DOMAIN
     if "issuer_keypair" not in kwds:
         kwds["issuer_keypair"] = (None, MOCKMYID_PRIVATE_KEY)
     return make_assertion(email, audience, **kwds)
Esempio n. 24
0
 def test_verifier_rejects_unallowed_issuers(self):
     config = self._make_config({  # noqa; indentation below is non-standard
         "browserid.audiences":
             "https://testmytoken.com",
         "browserid.allowed_issuers":
             "accounts.firefox.com mockmyid.com",
     })
     verifier = config.registry.getUtility(IBrowserIdVerifier)
     assertion = make_assertion(email="*****@*****.**",
                                audience="https://testmytoken.com")
     mock_response = {
         "status": "okay",
         "principal": {
             "email": "*****@*****.**",
         },
         "audience": "https://testmytoken.com",
         "issuer": "login.persona.org",
     }
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
     mock_response["issuer"] = "mockmyid.com"
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         self.assertEquals(verifier.verify(assertion)["principal"]["email"],
                           "*****@*****.**")
     mock_response["issuer"] = "accounts.firefox.com"
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         self.assertEquals(verifier.verify(assertion)["principal"]["email"],
                           "*****@*****.**")
     mock_response["issuer"] = "mockmyid.org"
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
     mock_response["issuer"] = "http://mockmyid.com"
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
     mock_response["issuer"] = "mockmyid.co"
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
     mock_response["issuer"] = 42
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
     mock_response["issuer"] = None
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
     del mock_response["issuer"]
     with self._mock_verifier(verifier, text=json.dumps(mock_response)):
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
 def test_audience_pattern_checking(self):
     verifier = LocalVerifier(["*.moz.com", "www.test.com"], warning=False)
     # Domains like *.moz.com should be valid audiences.
     # They will work with both the implicit patterns and explicit audience.
     assertion = make_assertion("*****@*****.**", "www.moz.com")
     self.assertTrue(verifier.verify(assertion))
     self.assertTrue(verifier.verify(assertion, "www.moz.com"))
     self.assertRaises(AudienceMismatchError, verifier.verify, assertion,
                       "www.test.com")
     # The specific domain www.test.com should be a valid audience.
     # It will work with both the implicit patterns and explicit audience.
     assertion = make_assertion("*****@*****.**", "www.test.com")
     self.assertTrue(verifier.verify(assertion))
     self.assertTrue(verifier.verify(assertion, "www.test.com"))
     self.assertRaises(AudienceMismatchError, verifier.verify, assertion,
                       "www.moz.com")
     # Domains not matching any patterns should not be valid audiences.
     # They will fail unless given as an explicit argument.
     assertion = make_assertion("*****@*****.**", "www.evil.com")
     self.assertRaises(AudienceMismatchError, verifier.verify, assertion)
     self.assertTrue(verifier.verify(assertion, "www.evil.com"))
Esempio n. 26
0
    def test_email_validation(self):
        verifier = LocalVerifier(audiences="http://persona.org")

        # Null bytes in the email hostname.
        assertion = make_assertion("[email protected]\x00.com",
                                   "http://persona.org")
        self.assertRaises(ValueError, verifier.verify, assertion)

        # Newlines in the email hostanem.
        assertion = make_assertion("[email protected]\[email protected]",
                                   "http://persona.org")
        self.assertRaises(ValueError, verifier.verify, assertion)

        # Null bytes in the email username.
        assertion = make_assertion(u"test\[email protected]",
                                   "http://persona.org")
        self.assertRaises(ValueError, verifier.verify, assertion)

        # Null bytes with regex-busting newline.
        assertion = make_assertion(u"[email protected]\u0000\[email protected]",
                                   "http://persona.org")
        self.assertRaises(ValueError, verifier.verify, assertion)
Esempio n. 27
0
    def test_email_validation(self):
        verifier = LocalVerifier(audiences="http://persona.org")

        # Null bytes in the email hostname.
        assertion = make_assertion("[email protected]\x00.com",
                                   "http://persona.org")
        self.assertRaises(ValueError, verifier.verify, assertion)

        # Newlines in the email hostanem.
        assertion = make_assertion("[email protected]\[email protected]",
                                   "http://persona.org")
        self.assertRaises(ValueError, verifier.verify, assertion)

        # Null bytes in the email username.
        assertion = make_assertion(u"test\[email protected]",
                                   "http://persona.org")
        self.assertRaises(ValueError, verifier.verify, assertion)

        # Null bytes with regex-busting newline.
        assertion = make_assertion(u"[email protected]\u0000\[email protected]",
                                   "http://persona.org")
        self.assertRaises(ValueError, verifier.verify, assertion)
 def test_verifier_rejects_unallowed_issuers(self):
     config = self._make_config({  # noqa; indentation below is non-standard
         "browserid.audiences":
             "https://testmytoken.com",
         "browserid.trusted_issuers":
             "accounts.firefox.com trustyidp.org",
         "browserid.allowed_issuers":
             "accounts.firefox.com mockmyid.com",
     })
     with patched_supportdoc_fetching():
         verifier = config.registry.getUtility(IBrowserIdVerifier)
         # The issuer is both trusted, and allowed.
         assertion = make_assertion(email="*****@*****.**",
                                    audience="https://testmytoken.com",
                                    issuer="accounts.firefox.com")
         self.assertEquals(verifier.verify(assertion)["email"],
                           "*****@*****.**")
         # The issuer is allowed and is the primary.
         assertion = make_assertion(email="*****@*****.**",
                                    audience="https://testmytoken.com",
                                    issuer="mockmyid.com")
         self.assertEquals(verifier.verify(assertion)["email"],
                           "*****@*****.**")
         # The issuer is allowed, but not trusted as a secondary.
         assertion = make_assertion(email="*****@*****.**",
                                    audience="https://testmytoken.com",
                                    issuer="mockmyid.com")
         with self.assertRaises(browserid.errors.InvalidSignatureError):
             verifier.verify(assertion)
         # The issuer is trsuted, but is not allowed.
         assertion = make_assertion(email="*****@*****.**",
                                    audience="https://testmytoken.com",
                                    issuer="trustyidp.org")
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
         # The issuer is the primary, but is not allowed.
         assertion = make_assertion(email="*****@*****.**",
                                    audience="https://testmytoken.com",
                                    issuer="example.com")
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
         # Various tests for string pattern-matching edgecases.
         # All of these are primaries, but not allowed.
         assertion = make_assertion(email="*****@*****.**",
                                    audience="https://testmytoken.com",
                                    issuer="mockmyid.org")
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
         assertion = make_assertion(email="*****@*****.**",
                                    audience="https://testmytoken.com",
                                    issuer="mockmyid.co")
         with self.assertRaises(browserid.errors.InvalidIssuerError):
             verifier.verify(assertion)
Esempio n. 29
0
    def test_well_known_doc_with_public_key(self):
        #  The browserid.org server doesn't currently have /.well-known/browserid.
        #  This simulates it with a dummy key.
        def urlopen(url, data):  # NOQA
            class response(object):
                @staticmethod
                def read():
                    key = fetch_public_key("browserid.org")
                    return json.dumps({"public-key": key})
            return response

        with patched_urlopen(urlopen):
            assertion = make_assertion("*****@*****.**", "http://e.com")
            self.assertTrue(self.verifier.verify(assertion))
Esempio n. 30
0
 def _make_browserid_assertion(self, email, **kwds):
     if "audience" not in kwds:
         kwds["audience"] = self.client.base_url
     if "exp" not in kwds:
         kwds["exp"] = int((time.time() + ONE_YEAR) * 1000)
     if "issuer" not in kwds:
         kwds["issuer"] = MOCKMYID_DOMAIN
     if "issuer_keypair" not in kwds:
         kwds["issuer_keypair"] = (None, MOCKMYID_PRIVATE_KEY)
     kwds["idp_claims"] = {
         'fxa-generation': self.generation_counter,
         'fxa-keysChangedAt': self.generation_counter,
     }
     return make_assertion(email, **kwds)
Esempio n. 31
0
    def test_cache_eviction_based_on_time(self):
        supportdocs = SupportDocumentManager(FIFOCache(cache_timeout=0.1))
        verifier = LocalVerifier(["*"], supportdocs=supportdocs)
        # Prime the cache by verifying an assertion.
        assertion = make_assertion("*****@*****.**", "")
        self.assertTrue(verifier.verify(assertion))
        # Make it error out if re-fetching the keys

        exc = RuntimeError("key fetch disabled")
        with patched_supportdoc_fetching(exc=exc):
            # It should be in the cache, so this works fine.
            self.assertTrue(verifier.verify(assertion))
            # But after sleeping it gets evicted and the error is triggered.
            time.sleep(0.1)
            self.assertRaises(RuntimeError, verifier.verify, assertion)
    def test_well_known_doc_with_public_key(self):
        #  The browserid.org server doesn't currently have /.well-known/browserid.
        #  This simulates it with a dummy key.
        def urlopen(url, data):  # NOQA
            class response(object):
                @staticmethod
                def read():
                    key = fetch_public_key("browserid.org")
                    return json.dumps({"public-key": key})

            return response

        with patched_urlopen(urlopen):
            assertion = make_assertion("*****@*****.**", "http://e.com")
            self.assertTrue(self.verifier.verify(assertion))
Esempio n. 33
0
    def test_cache_eviction_based_on_time(self):
        certs = CertificatesManager(FIFOCache(cache_timeout=0.1))
        verifier = LocalVerifier(["*"], certs=certs, warning=False)
        # Prime the cache by verifying an assertion.
        assertion = make_assertion("*****@*****.**", "")
        self.assertTrue(verifier.verify(assertion))
        # Make it error out if re-fetching the keys

        with patched_key_fetching(exc=RuntimeError("key fetch disabled")):
            verifier.fetch_public_key = fetch_public_key
            # It should be in the cache, so this works fine.
            verifier.verify(assertion)
            # But after sleeping it gets evicted and the error is triggered.
            time.sleep(0.1)
            self.assertRaises(RuntimeError, verifier.verify, assertion)
    def test_cache_eviction_based_on_time(self):
        certs = CertificatesManager(FIFOCache(cache_timeout=0.1))
        verifier = LocalVerifier(["*"], certs=certs, warning=False)
        # Prime the cache by verifying an assertion.
        assertion = make_assertion("*****@*****.**", "")
        self.assertTrue(verifier.verify(assertion))
        # Make it error out if re-fetching the keys

        with patched_key_fetching(exc=RuntimeError("key fetch disabled")):
            verifier.fetch_public_key = fetch_public_key
            # It should be in the cache, so this works fine.
            verifier.verify(assertion)
            # But after sleeping it gets evicted and the error is triggered.
            time.sleep(0.1)
            self.assertRaises(RuntimeError, verifier.verify, assertion)
Esempio n. 35
0
    def test_cache_eviction_based_on_time(self):
        supportdocs = SupportDocumentManager(FIFOCache(cache_timeout=0.1))
        verifier = LocalVerifier(["*"], supportdocs=supportdocs)
        # Prime the cache by verifying an assertion.
        assertion = make_assertion("*****@*****.**", "")
        self.assertTrue(verifier.verify(assertion))
        # Make it error out if re-fetching the keys

        exc = RuntimeError("key fetch disabled")
        with patched_supportdoc_fetching(exc=exc):
            # It should be in the cache, so this works fine.
            self.assertTrue(verifier.verify(assertion))
            # But after sleeping it gets evicted and the error is triggered.
            time.sleep(0.1)
            self.assertRaises(RuntimeError, verifier.verify, assertion)
Esempio n. 36
0
    def test_account_login_persona(self):
        from floof.views.account import account_login_persona as view

        def verify(request, next_url, flash_msg):
            response = view(request.context, request)
            flashes = request.session['_f_']
            assert len(flashes) == 1
            assert flash_msg in flashes[0]
            assert response['redirect-to'] == next_url

        audience = 'https://localhost'
        self.config.add_settings({'auth.persona.audience': audience})
        request = self._make_request()
        request.method = 'POST'
        request.user = sim.sim_user(credentials=[('persona', OLD_ASSERTION_ADDR)])

        # Test failures

        trials = (
            (None, 'unspecified error'),
            ('', 'unspecified error'),
            (self._randstr(), 'unspecified error'),
            (OLD_ASSERTION, 'signature was invalid')
        )

        for a, f in trials:
            request.POST = MultiDict({'assertion': a})
            verify(request,
                   next_url=request.route_url('account.login'),
                   flash_msg=f)
            request.session.clear()

        # Test success

        email = self._randstr() + '@example.com'
        verifier = LocalVerifier([audience], warning=False)
        a = make_assertion(email, audience)

        request.POST = MultiDict({'assertion': a})
        request.user = sim.sim_user(credentials=[('persona', email)])
        request.environ['paste.testing'] = True
        request.environ['tests.auth.persona.verifier'] = verifier
        request.environ['tests.auth.persona.audience'] = audience
        with patched_supportdoc_fetching():
            verify(request,
                   next_url=request.route_url('root'),
                   flash_msg='Re-authentication successful')
Esempio n. 37
0
    def test_account_login_persona(self):
        from floof.views.account import account_login_persona as view

        def verify(request, next_url, flash_msg):
            response = view(request.context, request)
            flashes = request.session['_f_']
            assert len(flashes) == 1
            assert flash_msg in flashes[0]
            assert response['redirect-to'] == next_url

        audience = 'https://localhost'
        self.config.add_settings({'auth.persona.audience': audience})
        request = self._make_request()
        request.method = 'POST'
        request.user = sim.sim_user(credentials=[('persona',
                                                  OLD_ASSERTION_ADDR)])

        # Test failures

        trials = ((None, 'unspecified error'), ('', 'unspecified error'),
                  (self._randstr(), 'unspecified error'),
                  (OLD_ASSERTION, 'signature was invalid'))

        for a, f in trials:
            request.POST = MultiDict({'assertion': a})
            verify(request,
                   next_url=request.route_url('account.login'),
                   flash_msg=f)
            request.session.clear()

        # Test success

        email = self._randstr() + '@example.com'
        verifier = LocalVerifier([audience], warning=False)
        a = make_assertion(email, audience)

        request.POST = MultiDict({'assertion': a})
        request.user = sim.sim_user(credentials=[('persona', email)])
        request.environ['paste.testing'] = True
        request.environ['tests.auth.persona.verifier'] = verifier
        request.environ['tests.auth.persona.audience'] = audience
        with patched_supportdoc_fetching():
            verify(request,
                   next_url=request.route_url('root'),
                   flash_msg='Re-authentication successful')
Esempio n. 38
0
 def test_extraction_of_extra_claims_from_principal(self):
     assertion = make_assertion("*****@*****.**", "http://e.com",
         idp_claims={
             "extra": "claim",
             "principal": {
                 "email": "*****@*****.**",
                 "another": "claim",
                 "public-key": "should-be-ignored",
             }
         },
     )
     result = self.verifier.verify(assertion)
     self.assertEqual(result["status"], "okay")
     self.assertEqual(result["idpClaims"], {
         "extra": "claim",
         "another": "claim",
     })
     self.assertTrue("userClaims" not in result)
Esempio n. 39
0
def get_assertion(email, audience="*", issuer='browserid.org',
        bad_issuer_cert=False, bad_email_cert=False, exp=None):
    """Creates a browserid assertion for the given email, audience and
    hostname.

    This function can also be used to create invalid assertions. This will be
    the case if you set the bad_issuer_cert or the bad_email cert arguments to
    True.
    """
    kwargs = {'exp': exp}
    if bad_issuer_cert:
        kwargs['issuer_keypair'] =\
                get_keypair(hostname="not-the-right-host.com")

    if bad_email_cert:
        kwargs['email_keypair'] =\
                get_keypair(hostname="not-the-right-host.com")

    return make_assertion(email, audience, issuer=issuer, **kwargs)
 def test_verifier_failure_cases(self):
     config = self._make_config({  # noqa; indentation below is non-standard
         "browserid.audiences":
             "https://testmytoken.com",
     })
     verifier = config.registry.getUtility(IBrowserIdVerifier)
     assertion = make_assertion(email="*****@*****.**",
                                audience="https://testmytoken.com")
     with self._mock_verifier(verifier, status_code=500):
         with self.assertRaises(browserid.errors.ConnectionError):
             verifier.verify(assertion)
     with self._mock_verifier(verifier, text="<h1>Server Error</h1>"):
         with self.assertRaises(browserid.errors.ConnectionError):
             verifier.verify(assertion)
     with self._mock_verifier(verifier, text='{"status": "error"}'):
         with self.assertRaises(browserid.errors.InvalidSignatureError):
             verifier.verify(assertion)
     with self._mock_verifier(verifier, text='{"status": "potato"}'):
         with self.assertRaises(browserid.errors.InvalidSignatureError):
             verifier.verify(assertion)
Esempio n. 41
0
 def test_extraction_of_extra_claims_from_principal(self):
     assertion = make_assertion(
         "*****@*****.**",
         "http://e.com",
         idp_claims={
             "extra": "claim",
             "principal": {
                 "email": "*****@*****.**",
                 "another": "claim",
                 "public-key": "should-be-ignored",
             }
         },
     )
     result = self.verifier.verify(assertion)
     self.assertEqual(result["status"], "okay")
     self.assertEqual(result["idpClaims"], {
         "extra": "claim",
         "another": "claim",
     })
     self.assertTrue("userClaims" not in result)
Esempio n. 42
0
 def test_verifier_failure_cases(self):
     config = self._make_config({  # noqa; indentation below is non-standard
         "browserid.audiences":
             "https://testmytoken.com",
     })
     verifier = config.registry.getUtility(IBrowserIdVerifier)
     assertion = make_assertion(email="*****@*****.**",
                                audience="https://testmytoken.com")
     with self._mock_verifier(verifier, status_code=500):
         with self.assertRaises(browserid.errors.ConnectionError):
             verifier.verify(assertion)
     with self._mock_verifier(verifier, text="<h1>Server Error</h1>"):
         with self.assertRaises(browserid.errors.ConnectionError):
             verifier.verify(assertion)
     with self._mock_verifier(verifier, text='{"status": "error"}'):
         with self.assertRaises(browserid.errors.InvalidSignatureError):
             verifier.verify(assertion)
     with self._mock_verifier(verifier, text='{"status": "potato"}'):
         with self.assertRaises(browserid.errors.InvalidSignatureError):
             verifier.verify(assertion)
Esempio n. 43
0
def get_assertion(email,
                  audience="*",
                  issuer='browserid.org',
                  bad_issuer_cert=False,
                  bad_email_cert=False,
                  exp=None):
    """Creates a browserid assertion for the given email, audience and
    hostname.

    This function can also be used to create invalid assertions. This will be
    the case if you set the bad_issuer_cert or the bad_email cert arguments to
    True.
    """
    kwargs = {'exp': exp}
    if bad_issuer_cert:
        kwargs['issuer_keypair'] =\
            get_keypair(hostname="not-the-right-host.com")

    if bad_email_cert:
        kwargs['email_keypair'] =\
            get_keypair(hostname="not-the-right-host.com")

    assertion = make_assertion(email, audience, issuer=issuer, **kwargs)
    return assertion.encode('ascii')
Esempio n. 44
0
 def _getassertion(self, **kw):
     kw.setdefault('email', '*****@*****.**')
     kw.setdefault('audience', 'http://tokenserver.services.mozilla.com')
     return make_assertion(**kw).encode('ascii')
Esempio n. 45
0
 def _make_assertion(self, email, **kwds):
     if "exp" not in kwds:
         kwds["exp"] = int((time.time() + ONE_YEAR) * 1000)
     return make_assertion(email, **kwds)
Esempio n. 46
0
 def test_verification_of_dummy_assertion_with_bad_certificate_sig(self):
     audience = "http://example.com"
     assertion = make_assertion("*****@*****.**", audience,
                                certificate_sig="CORRUPTUS")
     self.assertRaises(InvalidSignatureError, self.verifier.verify,
                       assertion)
Esempio n. 47
0
 def test_double_delegated_primary(self):
     assertion = make_assertion("*****@*****.**",
             "http://persona.org", issuer="delegated.org")
     self.assertTrue(self.verifier.verify(assertion))
Esempio n. 48
0
 def test_well_known_doc_with_public_key(self):
     assertion = make_assertion("*****@*****.**", "http://e.com")
     self.assertTrue(self.verifier.verify(assertion))
Esempio n. 49
0
 def _getassertion(self, **kw):
     kw.setdefault("email", "*****@*****.**")
     kw.setdefault("audience", "http://tokenserver.services.mozilla.com")
     return make_assertion(**kw).encode("ascii")
Esempio n. 50
0
 def test_browserid_is_supported(self):
     assertion = make_assertion('x', 'y').encode('ascii')
     res = self.app.get('/1.0/sync/1.1',
                        headers={'Authorization': 'BrowserID ' + assertion},
                        status=401)
     self.assertEqual(res.json['status'], 'invalid-credentials')
Esempio n. 51
0
 def test_verification_of_dummy_assertion_with_bad_certificate_sig(self):
     audience = "http://example.com"
     assertion = make_assertion("*****@*****.**", audience,
                                certificate_sig="CORRUPTUS")
     self.assertRaises(InvalidSignatureError, self.verifier.verify,
                       assertion)