+ q = self._query(self._db, table, UNIQUE_DATA_TABLE)
+ q.drop()
+ q.create()
+ q.commit()
+ except Exception, e: # pylint: disable=broad-except
+ if q:
+ q.rollback()
+ self.error("Failed to erase all data from %s: [%s]" % (table, e))
+
+
+class AdminStore(Store):
+ _should_cleanup = False
+
+ def __init__(self):
+ super(AdminStore, self).__init__('admin.config.db')
+
+ def get_data(self, plugin, idval=None, name=None, value=None):
+ return self.get_unique_data(plugin+"_data", idval, name, value)
+
+ def save_data(self, plugin, data):
+ return self.save_unique_data(plugin+"_data", data)
+
+ def new_datum(self, plugin, datum):
+ table = plugin+"_data"
+ return self.new_unique_data(table, datum)
+
+ def del_datum(self, plugin, idval):
+ table = plugin+"_data"
+ return self.del_unique_data(table, idval)
+
+ def wipe_data(self, plugin):
+ table = plugin+"_data"
+ self._reset_data(table)
+
+ def _initialize_schema(self):
+ for table in ['config',
+ 'info_config',
+ 'login_config',
+ 'provider_config']:
+ q = self._query(self._db, table, OPTIONS_TABLE, trans=False)
+ q.create()
+ q._con.close() # pylint: disable=protected-access
+
+ def _upgrade_schema(self, old_version):
+ if old_version == 1:
+ # In schema version 2, we added indexes and primary keys
+ for table in ['config',
+ 'info_config',
+ 'login_config',
+ 'provider_config']:
+ # pylint: disable=protected-access
+ table = self._query(self._db, table, OPTIONS_TABLE,
+ trans=False)._table
+ self._db.add_constraint(table.primary_key)
+ for index in table.indexes:
+ self._db.add_index(index)
+ return 2
+ else:
+ raise NotImplementedError()
+
+ def create_plugin_data_table(self, plugin_name):
+ if not self.is_readonly:
+ table = plugin_name+'_data'
+ q = self._query(self._db, table, UNIQUE_DATA_TABLE,
+ trans=False)
+ q.create()
+ q._con.close() # pylint: disable=protected-access
+
+
+class UserStore(Store):
+ _should_cleanup = False
+
+ def __init__(self, path=None):
+ super(UserStore, self).__init__('user.prefs.db')
+
+ def save_user_preferences(self, user, options):
+ self.save_options('users', user, options)
+
+ def load_user_preferences(self, user):
+ return self.load_options('users', user)
+
+ def save_plugin_data(self, plugin, user, options):
+ self.save_options(plugin+"_data", user, options)
+
+ def load_plugin_data(self, plugin, user):
+ return self.load_options(plugin+"_data", user)
+
+ def _initialize_schema(self):
+ q = self._query(self._db, 'users', OPTIONS_TABLE, trans=False)
+ q.create()
+ q._con.close() # pylint: disable=protected-access
+
+ 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, 'users', OPTIONS_TABLE,
+ trans=False)._table
+ self._db.add_constraint(table.primary_key)
+ for index in table.indexes:
+ self._db.add_index(index)
+ return 2
+ else:
+ raise NotImplementedError()
+
+ def create_plugin_data_table(self, plugin_name):
+ if not self.is_readonly:
+ table = plugin_name+'_data'
+ q = self._query(self._db, table, OPTIONS_TABLE,
+ trans=False)
+ q.create()
+ q._con.close() # pylint: disable=protected-access
+
+
+class TranStore(Store):
+
+ def __init__(self, path=None):
+ super(TranStore, self).__init__('transactions.db')
+ self.table = 'transactions'
+
+ def _initialize_schema(self):
+ q = self._query(self._db, self.table, UNIQUE_DATA_TABLE,
+ trans=False)
+ q.create()
+ q._con.close() # pylint: disable=protected-access
+
+ 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, self.table, UNIQUE_DATA_TABLE,
+ trans=False)._table
+ self._db.add_constraint(table.primary_key)
+ for index in table.indexes:
+ self._db.add_index(index)
+ return 2
+ else:
+ raise NotImplementedError()
+
+ def _cleanup(self):
+ # pylint: disable=protected-access
+ table = SqlQuery(self._db, self.table, UNIQUE_DATA_TABLE)._table
+ in_one_hour = datetime.datetime.now() - datetime.timedelta(hours=1)
+ sel = select([table.columns.uuid]). \
+ where(and_(table.c.name == 'origintime',
+ table.c.value <= in_one_hour))
+ # pylint: disable=no-value-for-parameter
+ d = table.delete().where(table.c.uuid.in_(sel))
+ return d.execute().rowcount
+
+
+class SAML2SessionStore(Store):
+
+ def __init__(self, database_url):
+ super(SAML2SessionStore, self).__init__(database_url=database_url)
+ self.table = 'saml2_sessions'
+ # pylint: disable=protected-access
+ table = SqlQuery(self._db, self.table, UNIQUE_DATA_TABLE)._table
+ table.create(checkfirst=True)
+
+ def _get_unique_id_from_column(self, name, value):
+ """
+ The query is going to return only the column in the query.
+ Use this method to get the uuidval which can be used to fetch
+ the entire entry.
+
+ Returns None or the uuid of the first value found.
+ """
+ data = self.get_unique_data(self.table, name=name, value=value)
+ count = len(data)
+ if count == 0:
+ return None
+ elif count != 1:
+ raise ValueError("Multiple entries returned")
+ return data.keys()[0]
+
+ def _cleanup(self):
+ # pylint: disable=protected-access
+ table = SqlQuery(self._db, self.table, UNIQUE_DATA_TABLE)._table
+ sel = select([table.columns.uuid]). \
+ where(and_(table.c.name == 'expiration_time',
+ table.c.value <= datetime.datetime.now()))
+ # pylint: disable=no-value-for-parameter
+ d = table.delete().where(table.c.uuid.in_(sel))
+ return d.execute().rowcount
+
+ def get_data(self, idval=None, name=None, value=None):
+ return self.get_unique_data(self.table, idval, name, value)
+
+ def new_session(self, datum):
+ if 'supported_logout_mechs' in datum:
+ datum['supported_logout_mechs'] = ','.join(
+ datum['supported_logout_mechs']
+ )
+ return self.new_unique_data(self.table, datum)
+
+ def get_session(self, session_id=None, request_id=None):
+ if session_id:
+ uuidval = self._get_unique_id_from_column('session_id', session_id)
+ elif request_id:
+ uuidval = self._get_unique_id_from_column('request_id', request_id)
+ else:
+ raise ValueError("Unable to find session")
+ if not uuidval:
+ return None, None
+ data = self.get_unique_data(self.table, uuidval=uuidval)
+ return uuidval, data[uuidval]
+
+ def get_user_sessions(self, user):
+ """
+ Return a list of all sessions for a given user.
+ """
+ rows = self.get_unique_data(self.table, name='user', value=user)
+
+ # We have a list of sessions for this user, now get the details
+ logged_in = []
+ for r in rows:
+ data = self.get_unique_data(self.table, uuidval=r)
+ data[r]['supported_logout_mechs'] = data[r].get(
+ 'supported_logout_mechs', '').split(',')
+ logged_in.append(data)
+
+ return logged_in
+
+ def update_session(self, datum):
+ self.save_unique_data(self.table, datum)
+
+ def remove_session(self, uuidval):
+ self.del_unique_data(self.table, uuidval)
+
+ def wipe_data(self):
+ self._reset_data(self.table)
+
+ def _initialize_schema(self):
+ q = self._query(self._db, self.table, UNIQUE_DATA_TABLE,
+ trans=False)
+ q.create()
+ q._con.close() # pylint: disable=protected-access
+
+ 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, self.table, UNIQUE_DATA_TABLE,
+ trans=False)._table
+ self._db.add_constraint(table.primary_key)
+ for index in table.indexes:
+ self._db.add_index(index)
+ return 2
+ else:
+ raise NotImplementedError()