From: Patrick Uiterwijk Date: Fri, 5 Dec 2014 17:28:21 +0000 (-0500) Subject: Add OpenIDStore to store associations and nonces X-Git-Tag: v0.3.0~4 X-Git-Url: http://git.cascardo.info/?p=cascardo%2Fipsilon.git;a=commitdiff_plain;h=a7232b6ff6edfcbe36dd44fc0419a71099fda4cb Add OpenIDStore to store associations and nonces Signed-off-by: Patrick Uiterwijk Reviewed-by: Simo Sorce --- diff --git a/ipsilon/providers/openid/store.py b/ipsilon/providers/openid/store.py new file mode 100755 index 0000000..9b426bc --- /dev/null +++ b/ipsilon/providers/openid/store.py @@ -0,0 +1,80 @@ +#!/usr/bin/python +# +# Copyright (C) 2014 Ipsilon project Contributors, for licensee see COPYING + +from ipsilon.util.data import Store + +from openid import oidutil +from openid.association import Association +from openid.store.nonce import SKEW as NonceSKEW +from openid.store.interface import OpenIDStore as OpenIDStoreInterface + +from time import time + +class OpenIDStore(Store, OpenIDStoreInterface): + def __init__(self, database_url): + Store.__init__(self, database_url=database_url) + + def storeAssociation(self, server_url, assoc): + iden = '%s-%s' % (server_url, assoc.handle) + datum = {'secret': oidutil.toBase64(assoc.secret), + 'issued': str(assoc.issued), + 'lifetime': str(assoc.lifetime), + 'assoc_type': assoc.assoc_type} + + data = {iden: datum} + self.save_unique_data('association', data) + + def getAssociation(self, server_url, handle=None): + iden = '%s-%s' % (server_url, handle) + data = self.get_unique_data('association', iden) + + if len(data) < 1: + return None + + datum = data[iden] + assoc = Association(handle, + oidutil.fromBase64(datum['secret']), + int(datum['issued']), + int(datum['lifetime']), + datum['assoc_type']) + + if assoc.expiresIn == 0: + self.del_unique_data('association', iden) + return None + + return assoc + + def removeAssociation(self, server_url, handle): + iden = '%s-%s' % (server_url, handle) + self.del_unique_data('association', iden) + + def useNonce(self, server_url, timestamp, salt): + if abs(timestamp - time()) > NonceSKEW: + return False + + iden = '%s-%s-%s' % (server_url, timestamp, salt) + data = self.get_unique_data('nonce', iden) + + if len(data) > 0: + # This server_url, timestamp, salt combination is already seen + return False + + datum = {'timestamp': timestamp} + data = {iden: datum} + self.save_unique_data('nonce', data) + + return True + + def cleanupNonces(self): + nonces = self.get_unique_data('nonce') + for iden in nonces: + if nonces[iden]['timestamp'] < (time() - NonceSKEW): + self.del_unique_data('nonce', iden) + + def cleanupAssociations(self): + assocs = self.get_unique_data('association') + for iden in assocs: + if ((int(assocs[iden]['issued']) + int(assocs[iden]['lifetime'])) + < time()): + self.del_unique_data('association', iden) diff --git a/ipsilon/providers/openidp.py b/ipsilon/providers/openidp.py index 7b53f78..08890a2 100755 --- a/ipsilon/providers/openidp.py +++ b/ipsilon/providers/openidp.py @@ -5,6 +5,7 @@ from __future__ import absolute_import from ipsilon.providers.common import ProviderBase +from ipsilon.providers.openid.store import OpenIDStore from ipsilon.providers.openid.auth import OpenID from ipsilon.providers.openid.extensions.common import LoadExtensions from ipsilon.util.plugin import PluginObject @@ -12,8 +13,6 @@ from ipsilon.util import config as pconfig from ipsilon.info.common import InfoMapping from openid.server.server import Server -# TODO: Move this to the database -from openid.store.memstore import MemoryStore class IdpProvider(ProviderBase): @@ -32,6 +31,10 @@ Provides OpenID 2.0 authentication infrastructure. """ self.new_config( self.name, + pconfig.String( + 'database url', + 'Database URL for OpenID temp storage', + 'openid.sqlite'), pconfig.String( 'default email domain', 'Used for users missing the email property.', @@ -96,7 +99,9 @@ Provides OpenID 2.0 authentication infrastructure. """ return self.page def init_idp(self): - self.server = Server(MemoryStore(), op_endpoint=self.endpoint_url) + self.server = Server( + OpenIDStore(self.get_config_value('database url')), + op_endpoint=self.endpoint_url) # Expose OpenID presence in the root headers = self._root.default_headers