From f525ec4944e4959fd9362fb4a0581f87751c0a0e Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Apr 29 2020 04:41:05 +0000 Subject: [PATCH 1/4] Create OpenID nonce table OpenIDStore registers the nonce table for automatic cleanup, but it's never created. Even though the table isn't required, a SQL error is logged every time automatic cleanup is triggered if it doesn't exist. Fixes: #240 Signed-off-by: Dan Nicholson --- diff --git a/ipsilon/providers/openid/store.py b/ipsilon/providers/openid/store.py index 3b36e25..d857d74 100644 --- a/ipsilon/providers/openid/store.py +++ b/ipsilon/providers/openid/store.py @@ -76,19 +76,21 @@ class OpenIDStore(Store, OpenIDStoreInterface): return def _initialize_schema(self): - q = self._query(self._db, 'association', UNIQUE_DATA_TABLE, - trans=False) - q.create() + for tablename in ['association', 'nonce']: + q = self._query(self._db, tablename, UNIQUE_DATA_TABLE, + trans=False) + q.create() def _upgrade_schema(self, old_version): if old_version == 1: # In schema version 2, we added indexes and primary keys # pylint: disable=protected-access - table = self._query(self._db, 'association', UNIQUE_DATA_TABLE, - trans=False)._table - self._db.add_constraint(table.primary_key) - for index in table.indexes: - self._db.add_index(index) + for tablename in ['association', 'nonce']: + table = self._query(self._db, tablename, UNIQUE_DATA_TABLE, + trans=False)._table + self._db.add_constraint(table.primary_key) + for index in table.indexes: + self._db.add_index(index) table = self._query(self._db, 'openid_extensions', OPTIONS_TABLE, trans=False)._table self._db.add_constraint(table.primary_key) From 72f6531c47b1cb5767bf6d7fad21fba4d01fb245 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Apr 29 2020 04:51:00 +0000 Subject: [PATCH 2/4] fix dbupgrade --- diff --git a/ipsilon/providers/openid/store.py b/ipsilon/providers/openid/store.py index d857d74..f2265d5 100644 --- a/ipsilon/providers/openid/store.py +++ b/ipsilon/providers/openid/store.py @@ -1,6 +1,7 @@ # Copyright (C) 2014 Ipsilon project Contributors, for license see COPYING -from ipsilon.util.data import Store, UNIQUE_DATA_TABLE, OPTIONS_TABLE +from ipsilon.util.data import (Store, UNIQUE_DATA_TABLE, OPTIONS_TABLE, + CURRENT_SCHEMA_VERSION) from openid import oidutil from openid.association import Association @@ -10,6 +11,9 @@ from openid.store.interface import OpenIDStore as OpenIDStoreInterface from time import time +CURRENT_OPENID_SCHEMA_VERSION = CURRENT_SCHEMA_VERSION + 1 + + class OpenIDStore(Store, OpenIDStoreInterface): _auto_cleanup_tables = ['association', 'nonce'] @@ -75,6 +79,9 @@ class OpenIDStore(Store, OpenIDStoreInterface): # This is automatically cleaned up return + def _code_schema_version(self): + return CURRENT_OPENID_SCHEMA_VERSION + def _initialize_schema(self): for tablename in ['association', 'nonce']: q = self._query(self._db, tablename, UNIQUE_DATA_TABLE, @@ -85,12 +92,11 @@ class OpenIDStore(Store, OpenIDStoreInterface): if old_version == 1: # In schema version 2, we added indexes and primary keys # pylint: disable=protected-access - for tablename in ['association', 'nonce']: - table = self._query(self._db, tablename, UNIQUE_DATA_TABLE, - trans=False)._table - self._db.add_constraint(table.primary_key) - for index in table.indexes: - self._db.add_index(index) + table = self._query(self._db, 'association', UNIQUE_DATA_TABLE, + trans=False)._table + self._db.add_constraint(table.primary_key) + for index in table.indexes: + self._db.add_index(index) table = self._query(self._db, 'openid_extensions', OPTIONS_TABLE, trans=False)._table self._db.add_constraint(table.primary_key) @@ -99,5 +105,11 @@ class OpenIDStore(Store, OpenIDStoreInterface): return 2 elif old_version == 2: return 3 + elif old_version == 3: + # In OpenID schema version 4 the missing nonce table was added + q = self._query(self._db, 'nonce', UNIQUE_DATA_TABLE, + trans=False) + q.create() + return 4 else: raise NotImplementedError() From 96c0e8d57025ea95aefc73455d46084e0ff0073e Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Apr 29 2020 04:52:34 +0000 Subject: [PATCH 3/4] openid dbupgrade test --- diff --git a/tests/blobs/old_dbs/v3/openid.sqlite.dump b/tests/blobs/old_dbs/v3/openid.sqlite.dump new file mode 100644 index 0000000..3fbcc12 --- /dev/null +++ b/tests/blobs/old_dbs/v3/openid.sqlite.dump @@ -0,0 +1,21 @@ +PRAGMA foreign_keys=OFF; +BEGIN TRANSACTION; +CREATE TABLE dbinfo ( + name TEXT NOT NULL, + option TEXT NOT NULL, + value TEXT +); +INSERT INTO "dbinfo" VALUES('OpenIDStore_schema','version','3'); +CREATE TABLE association ( + uuid TEXT NOT NULL, + name TEXT NOT NULL, + value TEXT +); +CREATE TABLE openid_extensions ( + name TEXT NOT NULL, + option TEXT NOT NULL, + value TEXT +); +CREATE INDEX idx_association_uuid ON association (uuid); +CREATE INDEX idx_openid_extensions_name ON openid_extensions (name); +COMMIT; From c4ac96ab9b4252365b011865481c6bdba23f5cb4 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Apr 29 2020 05:14:22 +0000 Subject: [PATCH 4/4] really add a test for openid version 4 upgrade --- diff --git a/tests/dbupgrades.py b/tests/dbupgrades.py index ce78712..cf6489d 100755 --- a/tests/dbupgrades.py +++ b/tests/dbupgrades.py @@ -10,6 +10,7 @@ import pwd import sys import signal import subprocess +from ipsilon.providers.openid.store import CURRENT_OPENID_SCHEMA_VERSION import ipsilon.util.data idp_g = {'TEMPLATES': '${TESTDIR}/templates/install', @@ -92,11 +93,16 @@ class IpsilonTest(IpsilonTestBase): self.use_readonly_adminconfig(name) if old_version > 0: - for database in ['adminconfig', + if old_version <= ipsilon.util.data.CURRENT_SCHEMA_VERSION: + databases = ['adminconfig', 'openid', 'saml2.sessions.db', 'transactions', - 'userprefs']: + 'userprefs'] + else: + databases = ['openid'] + + for database in databases: db_in = os.path.join(db_indir, '%s.sqlite.dump' % database) db_out = os.path.join(db_outdir, '%s.sqlite' % database) os.unlink(db_out) @@ -143,6 +149,15 @@ class IpsilonTest(IpsilonTestBase): raise Exception('Database upgrade did not introduce ' + 'authz_config table') + elif old_version > ipsilon.util.data.CURRENT_SCHEMA_VERSION: + # Database specific schema changes + if old_version == 3: + # OpenID version 4 added the nonce table + output = self.dump_db(db_outdir, with_readonly) + if b'TABLE nonce' not in output: + raise Exception('OpenID database upgrade did not ' + + 'introduce nonce table') + # Start the httpd server http_server = self.start_http_server(conf, env) @@ -180,6 +195,17 @@ class IpsilonTest(IpsilonTestBase): overall_exit_code = 1 overall_results.extend(results) + for version in range(ipsilon.util.data.CURRENT_SCHEMA_VERSION, + CURRENT_OPENID_SCHEMA_VERSION) + for with_readonly in [True, False]: + exit_code, results = self.test_upgrade_from(env, + version, + with_readonly) + + if exit_code != 0: + overall_exit_code = 1 + overall_results.extend(results) + return overall_exit_code, overall_results