예제 #1
0
    def setUp(self):
        self.store = GoodAssocStore()
        self.consumer = GenericConsumer(self.store)
        self.server_url = "http://idp.unittest/"
        CatchLogs.setUp(self)

        claimed_id = 'bogus.claimed'

        self.message = Message.fromOpenIDArgs(
            {'mode': 'id_res',
             'return_to': 'return_to (just anything)',
             'identity': claimed_id,
             'assoc_handle': 'does not matter',
             'sig': GOODSIG,
             'response_nonce': mkNonce(),
             'signed': 'identity,return_to,response_nonce,assoc_handle,claimed_id,op_endpoint',
             'claimed_id': claimed_id,
             'op_endpoint': self.server_url,
             'ns':OPENID2_NS,
             })

        self.endpoint = OpenIDServiceEndpoint()
        self.endpoint.server_url = self.server_url
        self.endpoint.claimed_id = claimed_id
        self.consumer._checkReturnTo = lambda unused1, unused2 : True
예제 #2
0
 def test_mkSplit(self):
     t = 42
     nonce_str = mkNonce(t)
     self.failUnless(nonce_re.match(nonce_str))
     et, salt = splitNonce(nonce_str)
     self.failUnlessEqual(len(salt), 6)
     self.failUnlessEqual(et, t)
예제 #3
0
 def test_mkSplit(self):
     t = 42
     nonce_str = mkNonce(t)
     self.failUnless(nonce_re.match(nonce_str))
     et, salt = splitNonce(nonce_str)
     self.failUnlessEqual(len(salt), 6)
     self.failUnlessEqual(et, t)
예제 #4
0
 def test_mkSplit(self):
     t = 42
     nonce_str = mkNonce(t)
     self.assertTrue(nonce_re.match(nonce_str))
     et, salt = splitNonce(nonce_str)
     self.assertEqual(len(salt), 6)
     self.assertEqual(et, t)
예제 #5
0
 def test_consumerNonceOpenID2(self):
     """OpenID 2 does not use consumer-generated nonce"""
     self.return_to = 'http://rt.unittest/?nonce=%s' % (mkNonce(),)
     self.response = Message.fromOpenIDArgs(
         {'return_to': self.return_to, 'ns':OPENID2_NS})
     self.failUnlessRaises(ProtocolError, self.consumer._idResCheckNonce,
                           self.response, self.endpoint)
     self.failUnlessLogEmpty()
예제 #6
0
 def test_openid1Success(self):
     """use consumer-generated nonce"""
     nonce_value = mkNonce()
     self.return_to = 'http://rt.unittest/?nonce=%s' % (nonce_value,)
     self.response = Message.fromOpenIDArgs({'return_to': self.return_to})
     self.response.setArg(BARE_NS, 'nonce', nonce_value)
     self.consumer._idResCheckNonce(self.response, self.endpoint)
     self.failUnlessLogEmpty()
예제 #7
0
 def test_successWithNoStore(self):
     """When there is no store, checking the nonce succeeds"""
     self.consumer.store = None
     self.response = Message.fromOpenIDArgs(
                               {'response_nonce': mkNonce(),
                                'ns':OPENID2_NS,
                                })
     self.consumer._idResCheckNonce(self.response, self.endpoint)
     self.failUnlessLogEmpty()
예제 #8
0
 def test_serverNonceOpenID1(self):
     """OpenID 1 does not use server-generated nonce"""
     self.response = Message.fromOpenIDArgs(
         {'ns':OPENID1_NS,
          'return_to': 'http://return.to/',
          'response_nonce': mkNonce(),})
     self.failUnlessRaises(ProtocolError, self.consumer._idResCheckNonce,
                           self.response, self.endpoint)
     self.failUnlessLogEmpty()
예제 #9
0
    def test_badNonce(self):
        """remove the nonce from the store

        From "Checking the Nonce"::

            When the Relying Party checks the signature on an assertion, the

            Relying Party SHOULD ensure that an assertion has not yet
            been accepted with the same value for "openid.response_nonce"
            from the same OP Endpoint URL.
        """
        nonce = mkNonce()
        stamp, salt = splitNonce(nonce)
        self.store.useNonce(self.server_url, stamp, salt)
        self.response = Message.fromOpenIDArgs(
                                  {'response_nonce': nonce,
                                   'ns':OPENID2_NS,
                                   })
        self.failUnlessRaises(ProtocolError, self.consumer._idResCheckNonce,
                              self.response, self.endpoint)
예제 #10
0
 def test_mkNonce(self):
     nonce = mkNonce()
     self.assertTrue(nonce_re.match(nonce))
     self.assertTrue(len(nonce) == 26)
예제 #11
0
 def test_mkNonce_when(self):
     nonce = mkNonce(0)
     self.assertTrue(nonce_re.match(nonce))
     self.assertTrue(nonce.startswith('1970-01-01T00:00:00Z'))
     self.assertTrue(len(nonce) == 26)
예제 #12
0
 def test_mkNonce_when(self):
     nonce = mkNonce(0)
     self.failUnless(nonce_re.match(nonce))
     self.failUnless(nonce.startswith('1970-01-01T00:00:00Z'))
     self.failUnless(len(nonce) == 26)
예제 #13
0
 def test_mkNonce_when(self):
     nonce = mkNonce(0)
     self.failUnless(nonce_re.match(nonce))
     self.failUnless(nonce.startswith('1970-01-01T00:00:00Z'))
     self.failUnless(len(nonce) == 26)
예제 #14
0
 def test_mkNonce(self):
     nonce = mkNonce()
     self.failUnless(nonce_re.match(nonce))
     self.failUnless(len(nonce) == 26)
예제 #15
0
 def test_mkNonce(self):
     nonce = mkNonce()
     self.assertIsNotNone(nonce_re.match(nonce))
     self.assertEqual(len(nonce), 26)
예제 #16
0
    store.storeAssociation(server_url + '3', assocValid2)

    cleaned = store.cleanupAssociations()
    assert cleaned == 2, cleaned

    ### Nonce functions

    def checkUseNonce(nonce, expected, server_url, msg=''):
        stamp, salt = split(nonce)
        actual = store.useNonce(server_url, stamp, salt)
        assert bool(actual) == bool(expected), "%r != %r: %s" % (actual, expected,
                                                                 msg)

    for url in [server_url, '']:
        # Random nonce (not in store)
        nonce1 = mkNonce()

        # A nonce is allowed by default
        checkUseNonce(nonce1, True, url)

        # Storing once causes useNonce to return True the first, and only
        # the first, time it is called after the store.
        checkUseNonce(nonce1, False, url)
        checkUseNonce(nonce1, False, url)

        # Nonces from when the universe was an hour old should not pass these days.
        old_nonce = mkNonce(3600)
        checkUseNonce(old_nonce, False, url, "Old nonce (%r) passed." % (old_nonce,))


    old_nonce1 = mkNonce(now - 20000)
예제 #17
0
 def test_mkNonce(self):
     nonce = mkNonce()
     self.failUnless(nonce_re.match(nonce))
     self.failUnless(len(nonce) == 26)
예제 #18
0
 def test_serverNonce(self):
     """use server-generated nonce"""
     self.response = Message.fromOpenIDArgs(
         {'ns':OPENID2_NS, 'response_nonce': mkNonce(),})
     self.consumer._idResCheckNonce(self.response, self.endpoint)
     self.failUnlessLogEmpty()
예제 #19
0
def testStore(store):
    """Make sure a given store has a minimum of API compliance. Call
    this function with an empty store.

    Raises AssertionError if the store does not work as expected.

    OpenIDStore -> NoneType
    """
    ### Association functions
    now = int(time.time())

    server_url = 'http://www.myopenid.com/openid'
    def genAssoc(issued, lifetime=600):
        sec = generateSecret(20)
        hdl = generateHandle(128)
        return Association(hdl, sec, now + issued, lifetime, 'HMAC-SHA1')

    def checkRetrieve(url, handle=None, expected=None):
        retrieved_assoc = store.getAssociation(url, handle)
        assert retrieved_assoc == expected, (retrieved_assoc, expected)
        if expected is not None:
            if retrieved_assoc is expected:
                print ('Unexpected: retrieved a reference to the expected '
                       'value instead of a new object')
            assert retrieved_assoc.handle == expected.handle
            assert retrieved_assoc.secret == expected.secret

    def checkRemove(url, handle, expected):
        present = store.removeAssociation(url, handle)
        assert bool(expected) == bool(present)

    assoc = genAssoc(issued=0)

    # Make sure that a missing association returns no result
    checkRetrieve(server_url)

    # Check that after storage, getting returns the same result
    store.storeAssociation(server_url, assoc)
    checkRetrieve(server_url, None, assoc)

    # more than once
    checkRetrieve(server_url, None, assoc)

    # Storing more than once has no ill effect
    store.storeAssociation(server_url, assoc)
    checkRetrieve(server_url, None, assoc)

    # Removing an association that does not exist returns not present
    checkRemove(server_url, assoc.handle + 'x', False)

    # Removing an association that does not exist returns not present
    checkRemove(server_url + 'x', assoc.handle, False)

    # Removing an association that is present returns present
    checkRemove(server_url, assoc.handle, True)

    # but not present on subsequent calls
    checkRemove(server_url, assoc.handle, False)

    # Put assoc back in the store
    store.storeAssociation(server_url, assoc)

    # More recent and expires after assoc
    assoc2 = genAssoc(issued=1)
    store.storeAssociation(server_url, assoc2)

    # After storing an association with a different handle, but the
    # same server_url, the handle with the later issue date is returned.
    checkRetrieve(server_url, None, assoc2)

    # We can still retrieve the older association
    checkRetrieve(server_url, assoc.handle, assoc)

    # Plus we can retrieve the association with the later issue date
    # explicitly
    checkRetrieve(server_url, assoc2.handle, assoc2)

    # More recent, and expires earlier than assoc2 or assoc. Make sure
    # that we're picking the one with the latest issued date and not
    # taking into account the expiration.
    assoc3 = genAssoc(issued=2, lifetime=100)
    store.storeAssociation(server_url, assoc3)

    checkRetrieve(server_url, None, assoc3)
    checkRetrieve(server_url, assoc.handle, assoc)
    checkRetrieve(server_url, assoc2.handle, assoc2)
    checkRetrieve(server_url, assoc3.handle, assoc3)

    checkRemove(server_url, assoc2.handle, True)

    checkRetrieve(server_url, None, assoc3)
    checkRetrieve(server_url, assoc.handle, assoc)
    checkRetrieve(server_url, assoc2.handle, None)
    checkRetrieve(server_url, assoc3.handle, assoc3)

    checkRemove(server_url, assoc2.handle, False)
    checkRemove(server_url, assoc3.handle, True)

    checkRetrieve(server_url, None, assoc)
    checkRetrieve(server_url, assoc.handle, assoc)
    checkRetrieve(server_url, assoc2.handle, None)
    checkRetrieve(server_url, assoc3.handle, None)

    checkRemove(server_url, assoc2.handle, False)
    checkRemove(server_url, assoc.handle, True)
    checkRemove(server_url, assoc3.handle, False)

    checkRetrieve(server_url, None, None)
    checkRetrieve(server_url, assoc.handle, None)
    checkRetrieve(server_url, assoc2.handle, None)
    checkRetrieve(server_url, assoc3.handle, None)

    checkRemove(server_url, assoc2.handle, False)
    checkRemove(server_url, assoc.handle, False)
    checkRemove(server_url, assoc3.handle, False)

    ### test expired associations
    # assoc 1: server 1, valid
    # assoc 2: server 1, expired
    # assoc 3: server 2, expired
    # assoc 4: server 3, valid
    assocValid1 = genAssoc(issued=-3600,lifetime=7200)
    assocValid2 = genAssoc(issued=-5)
    assocExpired1 = genAssoc(issued=-7200,lifetime=3600)
    assocExpired2 = genAssoc(issued=-7200,lifetime=3600)

    store.cleanupAssociations()
    store.storeAssociation(server_url + '1', assocValid1)
    store.storeAssociation(server_url + '1', assocExpired1)
    store.storeAssociation(server_url + '2', assocExpired2)
    store.storeAssociation(server_url + '3', assocValid2)

    cleaned = store.cleanupAssociations()
    assert cleaned == 2, cleaned

    ### Nonce functions

    def checkUseNonce(nonce, expected, server_url, msg=''):
        stamp, salt = split(nonce)
        actual = store.useNonce(server_url, stamp, salt)
        assert bool(actual) == bool(expected), "%r != %r: %s" % (actual, expected,
                                                                 msg)

    for url in [server_url, '']:
        # Random nonce (not in store)
        nonce1 = mkNonce()

        # A nonce is allowed by default
        checkUseNonce(nonce1, True, url)

        # Storing once causes useNonce to return True the first, and only
        # the first, time it is called after the store.
        checkUseNonce(nonce1, False, url)
        checkUseNonce(nonce1, False, url)

        # Nonces from when the universe was an hour old should not pass these days.
        old_nonce = mkNonce(3600)
        checkUseNonce(old_nonce, False, url, "Old nonce (%r) passed." % (old_nonce,))


    old_nonce1 = mkNonce(now - 20000)
    old_nonce2 = mkNonce(now - 10000)
    recent_nonce = mkNonce(now - 600)

    from openid.store import nonce as nonceModule
    orig_skew = nonceModule.SKEW
    try:
        nonceModule.SKEW = 0
        store.cleanupNonces()
        # Set SKEW high so stores will keep our nonces.
        nonceModule.SKEW = 100000
        assert store.useNonce(server_url, *split(old_nonce1))
        assert store.useNonce(server_url, *split(old_nonce2))
        assert store.useNonce(server_url, *split(recent_nonce))

        nonceModule.SKEW = 3600
        cleaned = store.cleanupNonces()
        assert cleaned == 2, "Cleaned %r nonces." % (cleaned,)

        nonceModule.SKEW = 100000
        # A roundabout method of checking that the old nonces were cleaned is
        # to see if we're allowed to add them again.
        assert store.useNonce(server_url, *split(old_nonce1))
        assert store.useNonce(server_url, *split(old_nonce2))
        # The recent nonce wasn't cleaned, so it should still fail.
        assert not store.useNonce(server_url, *split(recent_nonce))
    finally:
        nonceModule.SKEW = orig_skew
예제 #20
0
 def test_mkNonce(self):
     nonce = mkNonce()
     self.assertIsNotNone(nonce_re.match(nonce))
     self.assertEqual(len(nonce), 26)