signon 8.54

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

default-secrets-storage.cpp
Go to the documentation of this file.
1 /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of signon
4 *
5 * Copyright (C) 2011 Canonical Ltd.
6 *
7 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * version 2.1 as published by the Free Software Foundation.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 */
23
24 #include "default-secrets-storage.h"
25 #include "signond-common.h"
26
27 #define RETURN_IF_NOT_OPEN(retval) \
28 if (!isOpen()) { \
29 TRACE() << "Secrets DB is not available"; \
30 SignOn::CredentialsDBError error(QLatin1String("Not open"), \
31 SignOn::CredentialsDBError::NotOpen); \
32 setLastError(error); return retval; \
33 }
34
35 #define S(s) QLatin1String(s)
36
37 using namespace SignonDaemonNS;
38
39 bool SecretsDB::createTables()
40 {
41 QStringList createTableQuery = QStringList()
42 << QString::fromLatin1(
43 "CREATE TABLE CREDENTIALS"
44 "(id INTEGER NOT NULL UNIQUE,"
45 "username TEXT,"
46 "password TEXT,"
47 "PRIMARY KEY (id))")
48 << QString::fromLatin1(
49 "CREATE TABLE STORE"
50 "(identity_id INTEGER,"
51 "method_id INTEGER,"
52 "key TEXT,"
53 "value BLOB,"
54 "PRIMARY KEY (identity_id, method_id, key))")
55
56 << QString::fromLatin1(
57 // Cascading Delete
58 "CREATE TRIGGER tg_delete_credentials "
59 "BEFORE DELETE ON CREDENTIALS "
60 "FOR EACH ROW BEGIN "
61 " DELETE FROM STORE WHERE STORE.identity_id = OLD.id; "
62 "END; "
63 );
64
65 foreach (QString createTable, createTableQuery) {
66 QSqlQuery query = exec(createTable);
67 if (lastError().isValid()) {
68 TRACE() << "Error occurred while creating the database.";
69 return false;
70 }
71 query.clear();
72 commit();
73 }
74 return true;
75 }
76
77 bool SecretsDB::clear()
78 {
79 TRACE();
80
81 QStringList clearCommands = QStringList()
82 << QLatin1String("DELETE FROM CREDENTIALS")
83 << QLatin1String("DELETE FROM STORE");
84
85 return transactionalExec(clearCommands);
86 }
87
88 bool SecretsDB::updateCredentials(const quint32 id,
89 const QString &username,
90 const QString &password)
91 {
92 if (!startTransaction()) {
93 TRACE() << "Could not start transaction. Error inserting credentials.";
94 return false;
95 }
96 QSqlQuery query = newQuery();
97
98 TRACE() << "INSERT:" << id;
99 query.prepare(S("INSERT OR REPLACE INTO CREDENTIALS "
100 "(id, username, password) "
101 "VALUES(:id, :username, :password)"));
102
103 query.bindValue(S(":id"), id);
104 query.bindValue(S(":username"), username);
105 query.bindValue(S(":password"), password);
106
107 exec(query);
108
109 if (errorOccurred()) {
110 rollback();
111 TRACE() << "Error occurred while storing crendentials";
112 return false;
113 }
114 return commit();
115 }
116
117 bool SecretsDB::removeCredentials(const quint32 id)
118 {
119 TRACE();
120
121 QStringList queries = QStringList()
122 << QString::fromLatin1(
123 "DELETE FROM CREDENTIALS WHERE id = %1").arg(id)
124 << QString::fromLatin1(
125 "DELETE FROM STORE WHERE identity_id = %1").arg(id);
126
127 return transactionalExec(queries);
128 }
129
130 bool SecretsDB::loadCredentials(const quint32 id,
131 QString &username,
132 QString &password)
133 {
134 TRACE();
135
136 QString queryStr =
137 QString::fromLatin1("SELECT username, password FROM credentials "
138 "WHERE id = %1").arg(id);
139 QSqlQuery query = exec(queryStr);
140 if (!query.first()) {
141 TRACE() << "No result or invalid credentials query.";
142 return false;
143 }
144
145 username = query.value(0).toString();
146 password = query.value(1).toString();
147 return true;
148 }
149
150 QVariantMap SecretsDB::loadData(quint32 id, quint32 method)
151 {
152 TRACE();
153
154 QSqlQuery q = newQuery();
155 q.prepare(S("SELECT key, value "
156 "FROM STORE WHERE identity_id = :id AND method_id = :method"));
157 q.bindValue(S(":id"), id);
158 q.bindValue(S(":method"), method);
159 exec(q);
160 if (errorOccurred())
161 return QVariantMap();
162
163 QVariantMap result;
164 while (q.next()) {
165 QByteArray array;
166 array = q.value(1).toByteArray();
167 QDataStream stream(array);
168 QVariant data;
169 stream >> data;
170 result.insert(q.value(0).toString(), data);
171 }
172 return result;
173 }
174
175 bool SecretsDB::storeData(quint32 id, quint32 method, const QVariantMap &data)
176 {
177 TRACE();
178
179 if (!startTransaction()) {
180 TRACE() << "Could not start transaction. Error inserting data.";
181 return false;
182 }
183
184 /* first, remove existing data */
185 QSqlQuery q = newQuery();
186 q.prepare(S("DELETE FROM STORE WHERE identity_id = :id "
187 "AND method_id = :method"));
188 q.bindValue(S(":id"), id);
189 q.bindValue(S(":method"), method);
190 exec(q);
191 if (errorOccurred()) {
192 rollback();
193 TRACE() << "Data removal failed.";
194 return false;
195 }
196
197 bool allOk = true;
198 qint32 dataCounter = 0;
199 if (!(data.keys().empty())) {
200 QMapIterator<QString, QVariant> it(data);
201 while (it.hasNext()) {
202 it.next();
203
204 QByteArray array;
205 QDataStream stream(&array, QIODevice::WriteOnly);
206 stream << it.value();
207
208 dataCounter += it.key().size() +array.size();
209 if (dataCounter >= SSO_MAX_TOKEN_STORAGE) {
210 BLAME() << "storing data max size exceeded";
211 allOk = false;
212 break;
213 }
214 /* Key/value insert/replace/delete */
215 QSqlQuery query = newQuery();
216 if (!it.value().isValid() || it.value().isNull()) {
217 continue;
218 }
219 TRACE() << "insert";
220 query.prepare(S(
221 "INSERT OR REPLACE INTO STORE "
222 "(identity_id, method_id, key, value) "
223 "VALUES(:id, :method, :key, :value)"));
224 query.bindValue(S(":value"), array);
225 query.bindValue(S(":id"), id);
226 query.bindValue(S(":method"), method);
227 query.bindValue(S(":key"), it.key());
228 exec(query);
229 if (errorOccurred()) {
230 allOk = false;
231 break;
232 }
233 }
234 }
235
236 if (allOk && commit()) {
237 TRACE() << "Data insertion ok.";
238 return true;
239 }
240 rollback();
241 TRACE() << "Data insertion failed.";
242 return false;
243 }
244
245 bool SecretsDB::removeData(quint32 id, quint32 method)
246 {
247 TRACE();
248
249 if (!startTransaction()) {
250 TRACE() << "Could not start transaction. Error removing data.";
251 return false;
252 }
253
254 QSqlQuery q = newQuery();
255 if (method == 0) {
256 q.prepare(S("DELETE FROM STORE WHERE identity_id = :id"));
257 } else {
258 q.prepare(S("DELETE FROM STORE WHERE identity_id = :id "
259 "AND method_id = :method"));
260 q.bindValue(S(":method"), method);
261 }
262 q.bindValue(S(":id"), id);
263 exec(q);
264 if (!errorOccurred() && commit()) {
265 TRACE() << "Data removal ok.";
266 return true;
267 } else {
268 rollback();
269 TRACE() << "Data removal failed.";
270 return false;
271 }
272 }
273
274 DefaultSecretsStorage::DefaultSecretsStorage(QObject *parent):
275 AbstractSecretsStorage(parent)
276 {
277 }
278
279 DefaultSecretsStorage::~DefaultSecretsStorage()
280 {
281 close();
282 }
283
284 bool DefaultSecretsStorage::initialize(const QVariantMap &configuration)
285 {
286 if (isOpen()) {
287 TRACE() << "Initializing open DB; closing first...";
288 close();
289 }
290
291 QString name = configuration.value(QLatin1String("name")).toString();
292
293 m_secretsDB = new SecretsDB(name);
294 if (!m_secretsDB->init()) {
295 setLastError(m_secretsDB->lastError());
296 delete m_secretsDB;
297 m_secretsDB = 0;
298 return false;
299 }
300
301 setIsOpen(true);
302 return true;
303 }
304
305 bool DefaultSecretsStorage::close()
306 {
307 if (m_secretsDB != 0) {
308 QString connectionName = m_secretsDB->connectionName();
309 delete m_secretsDB;
310 QSqlDatabase::removeDatabase(connectionName);
311 m_secretsDB = 0;
312 }
313 return AbstractSecretsStorage::close();
314 }
315
316 bool DefaultSecretsStorage::clear()
317 {
318 RETURN_IF_NOT_OPEN(false);
319
320 return m_secretsDB->clear();
321 }
322
323 bool DefaultSecretsStorage::updateCredentials(const quint32 id,
324 const QString &username,
325 const QString &password)
326 {
327 RETURN_IF_NOT_OPEN(false);
328
329 return m_secretsDB->updateCredentials(id, username, password);
330 }
331
332 bool DefaultSecretsStorage::removeCredentials(const quint32 id)
333 {
334 RETURN_IF_NOT_OPEN(false);
335
336 return m_secretsDB->removeCredentials(id);
337 }
338
339 bool DefaultSecretsStorage::loadCredentials(const quint32 id,
340 QString &username,
341 QString &password)
342 {
343 RETURN_IF_NOT_OPEN(false);
344
345 return m_secretsDB->loadCredentials(id, username, password);
346 }
347
348 QVariantMap DefaultSecretsStorage::loadData(quint32 id, quint32 method)
349 {
350 RETURN_IF_NOT_OPEN(QVariantMap());
351
352 return m_secretsDB->loadData(id, method);
353 }
354
355 bool DefaultSecretsStorage::storeData(quint32 id, quint32 method,
356 const QVariantMap &data)
357 {
358 RETURN_IF_NOT_OPEN(false);
359
360 return m_secretsDB->storeData(id, method, data);
361 }
362
363 bool DefaultSecretsStorage::removeData(quint32 id, quint32 method)
364 {
365 RETURN_IF_NOT_OPEN(false);
366
367 return m_secretsDB->removeData(id, method);
368 }
SignonDaemonNS::SqlDatabase::startTransaction
bool startTransaction()
Definition: credentialsdb.cpp:193
SignonDaemonNS::SqlDatabase::exec
QSqlQuery exec(const QString &query)
Executes a specific database query.
Definition: credentialsdb.cpp:209
SignonDaemonNS::SecretsDB::updateCredentials
bool updateCredentials(const quint32 id, const QString &username, const QString &password)
Definition: default-secrets-storage.cpp:88
SignonDaemonNS::DefaultSecretsStorage::removeData
bool removeData(quint32 id, quint32 method)
Definition: default-secrets-storage.cpp:363
SignonDaemonNS::DefaultSecretsStorage::updateCredentials
bool updateCredentials(const quint32 id, const QString &username, const QString &password)
Definition: default-secrets-storage.cpp:323
SignonDaemonNS::DefaultSecretsStorage::close
bool close()
Definition: default-secrets-storage.cpp:305
SignonDaemonNS::DefaultSecretsStorage::DefaultSecretsStorage
DefaultSecretsStorage(QObject *parent=0)
Definition: default-secrets-storage.cpp:274
SignonDaemonNS::SecretsDB::removeData
bool removeData(quint32 id, quint32 method)
Definition: default-secrets-storage.cpp:245
SignonDaemonNS::DefaultSecretsStorage::removeCredentials
bool removeCredentials(const quint32 id)
Definition: default-secrets-storage.cpp:332
SignonDaemonNS::SecretsDB::loadData
QVariantMap loadData(quint32 id, quint32 method)
Definition: default-secrets-storage.cpp:150
SignonDaemonNS::SecretsDB::storeData
bool storeData(quint32 id, quint32 method, const QVariantMap &data)
Definition: default-secrets-storage.cpp:175
BLAME
#define BLAME()
Definition: debug.h:32
SignonDaemonNS::DefaultSecretsStorage::storeData
bool storeData(quint32 id, quint32 method, const QVariantMap &data)
Definition: default-secrets-storage.cpp:355
signond-common.h
SSO_MAX_TOKEN_STORAGE
#define SSO_MAX_TOKEN_STORAGE
Definition: credentialsdb.h:41
SignonDaemonNS::SqlDatabase::commit
bool commit()
Definition: credentialsdb.cpp:198
SignonDaemonNS::SqlDatabase::lastError
SignOn::CredentialsDBError lastError() const
Definition: credentialsdb.cpp:270
SignonDaemonNS::DefaultSecretsStorage::~DefaultSecretsStorage
~DefaultSecretsStorage()
Definition: default-secrets-storage.cpp:279
SignonDaemonNS::DefaultSecretsStorage::initialize
bool initialize(const QVariantMap &configuration)
Definition: default-secrets-storage.cpp:284
SignonDaemonNS::SecretsDB::removeCredentials
bool removeCredentials(const quint32 id)
Definition: default-secrets-storage.cpp:117
SignonDaemonNS::SecretsDB
Definition: default-secrets-storage.h:41
SignonDaemonNS::SqlDatabase::init
bool init()
Connects to the DB and if necessary creates the tables.
Definition: credentialsdb.cpp:144
SignonDaemonNS::SecretsDB::clear
bool clear()
Definition: default-secrets-storage.cpp:77
default-secrets-storage.h
SignonDaemonNS::SqlDatabase::errorOccurred
bool errorOccurred() const
Definition: credentialsdb_p.h:219
SignonDaemonNS::DefaultSecretsStorage::loadData
QVariantMap loadData(quint32 id, quint32 method)
Definition: default-secrets-storage.cpp:348
SignonDaemonNS::DefaultSecretsStorage::loadCredentials
bool loadCredentials(const quint32 id, QString &username, QString &password)
Definition: default-secrets-storage.cpp:339
TRACE
#define TRACE()
Definition: debug.h:28
SignonDaemonNS::SqlDatabase::transactionalExec
bool transactionalExec(const QStringList &queryList)
Executes a specific database set of queryes (INSERTs, UPDATEs, DELETEs) in a transaction context (No ...
Definition: credentialsdb.cpp:240
SignonDaemonNS::SqlDatabase::rollback
void rollback()
Definition: credentialsdb.cpp:203
SignonDaemonNS::SqlDatabase::newQuery
QSqlQuery newQuery() const
Definition: credentialsdb_p.h:169
SignonDaemonNS::SecretsDB::loadCredentials
bool loadCredentials(const quint32 id, QString &username, QString &password)
Definition: default-secrets-storage.cpp:130
SignonDaemonNS::SqlDatabase::connectionName
QString connectionName() const
Definition: credentialsdb_p.h:229
SignonDaemonNS::DefaultSecretsStorage::clear
bool clear()
Definition: default-secrets-storage.cpp:316
SignonDaemonNS::SecretsDB::createTables
bool createTables()
Definition: default-secrets-storage.cpp:39
S
#define S(s)
Definition: default-secrets-storage.cpp:35
RETURN_IF_NOT_OPEN
#define RETURN_IF_NOT_OPEN(retval)
Definition: default-secrets-storage.cpp:27