Introduction
============

Lets start by importing some modules we will be using:

  >>> from plone.openid.store import ZopeStore
  >>> from openid.association import Association
  >>> import time

Next we create a store object:

  >>> store = ZopeStore()


Associations
============

Lets create a new association:

  >>> now = int(time.time())
  >>> a = Association(handle="handle", secret="secret", issued=now,
  ...                 lifetime=600, assoc_type="HMAC-SHA1")

We can store the association and retrieve it via a server_url and its handle:

  >>> store.storeAssociation("http://localhost", a)
  >>> b = store.getAssociation("http://localhost", "handle")
  >>> a == b
  True

If we ask for an association with a None handle the store should still
return an assocation for the server:

  >>> b = store.getAssociation("http://localhost", None)
  >>> a == b
  True

Trying to retrieve a non-existing association should return None:

  >>> store.getAssociation("http://nothere") is None
  True
  >>> store.getAssociation("http://localhost", "nothere") is None
  True

Associations can be removed based on their server_url and handle. The
return value for removeAssociation indicates if an assocation has been
removed.

  >>> store.removeAssociation("http://localhost", "handle")
  True
  >>> store.removeAssociation("http://localhost", "handle")
  False

In an attempt to clean up expired associations retrieving them will
automatically remove them:

  >>> a = Association(handle="handle", secret="secret", issued=now-10,
  ...                 lifetime=5, assoc_type="HMAC-SHA1")
  >>> store.storeAssociation("http://localhost", a)
  >>> store.cleanupAssociations()
  1

  >>> store.getAssociation("http://localhost", "handle") is None
  True
  >>> store.cleanupAssociations()
  0

Getting an association without specifying a handle should work even
when the current handles are empty.

  >>> store.getAssociation("http://localhost") is None
  True

Nonces
======

OpenId uses nonces, which are basically ids used to track outstanding requests.
A nonce is build up from a server URL, a timestamp and a salt. The timestamp is
the time that the nonce was created (to the nearest second). The salt is a
random string that makes two nonces from the same server issued during the same
second unique. The timestamp is also used to track when old nonces should be
expired.

Using nonces the first time results in a True response

  >>> store.useNonce("one", now, "salt")
  True
  >>> store.useNonce("two", now, "salt")
  True

If we try to add a nonce which already exists False should be returned:

  >>> store.useNonce("two", now, "salt")
  False

But when there is a new request with a new timestamp, using nonces will result
in a True for a once again:

  >>> store.useNonce("two", now + 60, "salt")
  True
  >>> store.useNonce("two", now + 60, "salt")
  False