Пример #1
0
class TestCoreClient(unittest.TestCase):

    server_url = TEST_SERVER_URL

    def setUp(self):
        self.client = Client(self.server_url)
        self._accounts_to_delete = []

    def tearDown(self):
        for acct in self._accounts_to_delete:
            acct.clear()
            try:
                stretchpwd = acct.stretchpwd
            except AttributeError:
                try:
                    password = acct.password
                    stretchpwd = quick_stretch_password(acct.email, password)
                except AttributeError:
                    stretchpwd = DUMMY_STRETCHED_PASSWORD
            self.client.destroy_account(acct.email, stretchpwd=stretchpwd)

    def test_account_creation(self):
        acct = TestEmailAccount()
        acct.password = DUMMY_PASSWORD
        session = self.client.create_account(acct.email, DUMMY_PASSWORD)
        self._accounts_to_delete.append(acct)
        self.assertEqual(session.email, acct.email)
        self.assertFalse(session.verified)
        self.assertEqual(session.keys, None)
        self.assertEqual(session._key_fetch_token, None)
        with self.assertRaises(Exception):
            session.fetch_keys()

    def test_account_creation_with_key_fetch(self):
        acct = TestEmailAccount()
        session = self.client.create_account(
            email=acct.email,
            stretchpwd=DUMMY_STRETCHED_PASSWORD,
            keys=True,
        )
        self._accounts_to_delete.append(acct)
        self.assertEqual(session.email, acct.email)
        self.assertFalse(session.verified)
        self.assertEqual(session.keys, None)
        self.assertNotEqual(session._key_fetch_token, None)

    def test_account_login(self):
        acct = TestEmailAccount()
        session1 = self.client.create_account(
            email=acct.email,
            stretchpwd=DUMMY_STRETCHED_PASSWORD,
        )
        self._accounts_to_delete.append(acct)
        session2 = self.client.login(
            email=acct.email,
            stretchpwd=DUMMY_STRETCHED_PASSWORD,
        )
        self.assertEqual(session1.email, session2.email)
        self.assertNotEqual(session1.token, session2.token)

    def test_get_random_bytes(self):
        b1 = self.client.get_random_bytes()
        b2 = self.client.get_random_bytes()
        self.assertTrue(isinstance(b1, binary_type))
        self.assertNotEqual(b1, b2)

    def test_resend_verify_code(self):
        acct = TestEmailAccount()
        session = self.client.create_account(
            email=acct.email,
            stretchpwd=DUMMY_STRETCHED_PASSWORD,
        )
        self._accounts_to_delete.append(acct)

        def is_verify_email(m):
            return "x-verify-code" in m["headers"]

        m1 = acct.wait_for_email(is_verify_email)
        code1 = m1["headers"]["x-verify-code"]  # NOQA
        acct.clear()
        session.resend_email_code()
        # XXX TODO: this won't work against a live server because we
        # refuse to send duplicate emails within a short timespan.
        # m2 = acct.wait_for_email(is_verify_email)
        # code2 = m2["headers"]["x-verify-code"]
        # self.assertNotEqual(m1, m2)
        # self.assertEqual(code1, code2)

    def test_forgot_password_flow(self):
        acct = TestEmailAccount()
        self.client.create_account(
            email=acct.email,
            stretchpwd=DUMMY_STRETCHED_PASSWORD,
        )
        self._accounts_to_delete.append(acct)

        # Initiate the password reset flow, and grab the verification code.
        pftok = self.client.send_reset_code(acct.email, service="foobar")
        m = acct.wait_for_email(lambda m: "x-recovery-code" in m["headers"])
        if not m:
            raise RuntimeError("Password reset email was not received")
        acct.clear()
        code = m["headers"]["x-recovery-code"]

        # Try with an invalid code to test error handling.
        tries = pftok.tries_remaining
        self.assertTrue(tries > 1)
        with self.assertRaises(Exception):
            pftok.verify_code(mutate_one_byte(code))
        pftok.get_status()
        self.assertEqual(pftok.tries_remaining, tries - 1)

        # Re-send the code, as if we've lost the email.
        pftok.resend_code()
        m = acct.wait_for_email(lambda m: "x-recovery-code" in m["headers"])
        if not m:
            raise RuntimeError("Password reset email was not received")
        self.assertEqual(m["headers"]["x-recovery-code"], code)

        # Now verify with the actual code, and reset the account.
        artok = pftok.verify_code(code)
        self.client.reset_account(email=acct.email,
                                  token=artok,
                                  stretchpwd=DUMMY_STRETCHED_PASSWORD)

    def test_email_code_verification(self):
        self.client = Client(self.server_url)
        # Create a fresh testing account.
        self.acct = TestEmailAccount()
        self.client.create_account(
            email=self.acct.email,
            stretchpwd=DUMMY_STRETCHED_PASSWORD,
        )

        def wait_for_email(m):
            return "x-uid" in m["headers"] and "x-verify-code" in m["headers"]

        m = self.acct.wait_for_email(wait_for_email)
        if not m:
            raise RuntimeError("Verification email was not received")
        # If everything went well, verify_email_code should return an empty json object
        response = self.client.verify_email_code(m["headers"]["x-uid"],
                                                 m["headers"]["x-verify-code"])
        self.assertEquals(response, {})

    def test_send_unblock_code(self):
        acct = TestEmailAccount(email="block-{uniq}@{hostname}")
        self.client.create_account(
            email=acct.email,
            stretchpwd=DUMMY_STRETCHED_PASSWORD,
        )
        self._accounts_to_delete.append(acct)

        # Initiate sending unblock code
        response = self.client.send_unblock_code(acct.email)
        self.assertEquals(response, {})

        m = acct.wait_for_email(lambda m: "x-unblock-code" in m["headers"])
        if not m:
            raise RuntimeError("Unblock code email was not received")

        code = m["headers"]["x-unblock-code"]
        self.assertTrue(len(code) > 0)

        self.client.login(email=acct.email,
                          stretchpwd=DUMMY_STRETCHED_PASSWORD,
                          unblock_code=code)
Пример #2
0
class TestCoreClient(unittest.TestCase):

    server_url = TEST_SERVER_URL

    def setUp(self):
        self.client = Client(self.server_url)
        self._accounts_to_delete = []

    def tearDown(self):
        for acct in self._accounts_to_delete:
            acct.clear()
            try:
                stretchpwd = acct.stretchpwd
            except AttributeError:
                try:
                    password = acct.password
                    stretchpwd = quick_stretch_password(acct.email, password)
                except AttributeError:
                    stretchpwd = DUMMY_STRETCHED_PASSWORD
            self.client.destroy_account(acct.email, stretchpwd=stretchpwd)

    def test_account_creation(self):
        acct = TestEmailAccount()
        acct.password = DUMMY_PASSWORD
        session = self.client.create_account(acct.email, DUMMY_PASSWORD)
        self._accounts_to_delete.append(acct)
        self.assertEqual(session.email, acct.email)
        self.assertFalse(session.verified)
        self.assertEqual(session.keys, None)
        self.assertEqual(session._key_fetch_token, None)
        with self.assertRaises(Exception):
            session.fetch_keys()

    def test_account_creation_with_key_fetch(self):
        acct = TestEmailAccount()
        session = self.client.create_account(
            email=acct.email,
            stretchpwd=DUMMY_STRETCHED_PASSWORD,
            keys=True,
        )
        self._accounts_to_delete.append(acct)
        self.assertEqual(session.email, acct.email)
        self.assertFalse(session.verified)
        self.assertEqual(session.keys, None)
        self.assertNotEqual(session._key_fetch_token, None)

    def test_account_login(self):
        acct = TestEmailAccount()
        session1 = self.client.create_account(
            email=acct.email,
            stretchpwd=DUMMY_STRETCHED_PASSWORD,
        )
        self._accounts_to_delete.append(acct)
        session2 = self.client.login(
            email=acct.email,
            stretchpwd=DUMMY_STRETCHED_PASSWORD,
        )
        self.assertEqual(session1.email, session2.email)
        self.assertNotEqual(session1.token, session2.token)

    def test_get_random_bytes(self):
        b1 = self.client.get_random_bytes()
        b2 = self.client.get_random_bytes()
        self.assertTrue(isinstance(b1, binary_type))
        self.assertNotEqual(b1, b2)

    def test_resend_verify_code(self):
        acct = TestEmailAccount()
        session = self.client.create_account(
            email=acct.email,
            stretchpwd=DUMMY_STRETCHED_PASSWORD,
        )
        self._accounts_to_delete.append(acct)

        def is_verify_email(m):
            return "x-verify-code" in m["headers"]

        m1 = acct.wait_for_email(is_verify_email)
        code1 = m1["headers"]["x-verify-code"]  # NOQA
        acct.clear()
        session.resend_email_code()
        # XXX TODO: this won't work against a live server because we
        # refuse to send duplicate emails within a short timespan.
        # m2 = acct.wait_for_email(is_verify_email)
        # code2 = m2["headers"]["x-verify-code"]
        # self.assertNotEqual(m1, m2)
        # self.assertEqual(code1, code2)

    def test_forgot_password_flow(self):
        acct = TestEmailAccount()
        self.client.create_account(
            email=acct.email,
            stretchpwd=DUMMY_STRETCHED_PASSWORD,
        )
        self._accounts_to_delete.append(acct)

        # Initiate the password reset flow, and grab the verification code.
        pftok = self.client.send_reset_code(acct.email, service="foobar")
        m = acct.wait_for_email(lambda m: "x-recovery-code" in m["headers"])
        if not m:
            raise RuntimeError("Password reset email was not received")
        acct.clear()
        code = m["headers"]["x-recovery-code"]

        # Try with an invalid code to test error handling.
        tries = pftok.tries_remaining
        self.assertTrue(tries > 1)
        with self.assertRaises(Exception):
            pftok.verify_code(mutate_one_byte(code))
        pftok.get_status()
        self.assertEqual(pftok.tries_remaining, tries - 1)

        # Re-send the code, as if we've lost the email.
        pftok.resend_code()
        m = acct.wait_for_email(lambda m: "x-recovery-code" in m["headers"])
        if not m:
            raise RuntimeError("Password reset email was not received")
        self.assertEqual(m["headers"]["x-recovery-code"], code)

        # Now verify with the actual code, and reset the account.
        artok = pftok.verify_code(code)
        self.client.reset_account(
            email=acct.email,
            token=artok,
            stretchpwd=DUMMY_STRETCHED_PASSWORD
        )

    def test_email_code_verification(self):
        self.client = Client(self.server_url)
        # Create a fresh testing account.
        self.acct = TestEmailAccount()
        self.client.create_account(
            email=self.acct.email,
            stretchpwd=DUMMY_STRETCHED_PASSWORD,
        )

        def wait_for_email(m):
            return "x-uid" in m["headers"] and "x-verify-code" in m["headers"]

        m = self.acct.wait_for_email(wait_for_email)
        if not m:
            raise RuntimeError("Verification email was not received")
        # If everything went well, verify_email_code should return an empty json object
        response = self.client.verify_email_code(m["headers"]["x-uid"],
                                                 m["headers"]["x-verify-code"])
        self.assertEquals(response, {})

    def test_send_unblock_code(self):
        acct = TestEmailAccount(email="block-{uniq}@{hostname}")
        self.client.create_account(
            email=acct.email,
            stretchpwd=DUMMY_STRETCHED_PASSWORD,
        )
        self._accounts_to_delete.append(acct)

        # Initiate sending unblock code
        response = self.client.send_unblock_code(acct.email)
        self.assertEquals(response, {})

        m = acct.wait_for_email(lambda m: "x-unblock-code" in m["headers"])
        if not m:
            raise RuntimeError("Unblock code email was not received")

        code = m["headers"]["x-unblock-code"]
        self.assertTrue(len(code) > 0)

        self.client.login(
            email=acct.email,
            stretchpwd=DUMMY_STRETCHED_PASSWORD,
            unblock_code=code
        )