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