32 #define INIT_ERROR() ErrorMonitor errorMonitor(this) 33 #define RETURN_IF_NO_SECRETS_DB(retval) \ 34 if (!isSecretsDBOpen()) { \ 35 TRACE() << "Secrets DB is not available"; \ 36 _lastError = noSecretsDB; return retval; \ 39 #define S(s) QLatin1String(s) 43 static const QString driver = QLatin1String(
"QSQLITE");
47 QString &password)
const 49 QHash<quint32, AuthCache>::const_iterator i;
52 if (i == m_cache.end())
return false;
54 username = i->m_username;
55 password = i->m_password;
61 return m_cache.value(
id).m_blobData.value(method);
65 const QString &username,
66 const QString &password,
72 credentials.m_username = username;
73 credentials.m_password = password;
74 credentials.m_storePassword = storePassword;
78 const QVariantMap &data)
83 credentials.m_blobData[method] = data;
89 if (m_cache.isEmpty())
return;
91 TRACE() <<
"Storing cached credentials into permanent storage";
93 QHash<quint32, AuthCache>::const_iterator i;
94 for (i = m_cache.constBegin();
95 i != m_cache.constEnd();
101 QString password = cache.m_storePassword ?
102 cache.m_password : QString();
103 if (!cache.m_username.isEmpty() || !password.isEmpty()) {
104 secretsStorage->updateCredentials(
id,
110 QHash<quint32, QVariantMap>::const_iterator j;
111 for (j = cache.m_blobData.constBegin();
112 j != cache.m_blobData.constEnd();
114 quint32 method = j.key();
115 secretsStorage->storeData(
id, method, j.value());
126 const QString &connectionName,
128 m_lastError(
SignOn::CredentialsDBError()),
130 m_database(QSqlDatabase::addDatabase(driver, connectionName))
134 TRACE() <<
"DATABASE NAME [" << databaseName <<
"]";
150 TRACE() <<
"Database connection succeeded.";
153 TRACE() <<
"Creating SQL table structure...";
159 <<
".This could lead to data loss.";
161 TRACE() <<
"SQL table structure already created...";
163 QSqlQuery q =
exec(
S(
"PRAGMA user_version"));
164 int oldVersion = q.first() ? q.value(0).toInt() : 0;
174 TRACE() <<
"Update DB from version " << version <<
" to " <<
m_version;
175 exec(QString::fromLatin1(
"PRAGMA user_version = %1").arg(m_version));
182 TRACE() <<
"Could not open database connection.\n";
207 TRACE() <<
"Rollback failed, db data integrity could be compromised.";
214 if (!query.prepare(queryStr))
215 TRACE() <<
"Query prepare warning: " << query.lastQuery();
218 TRACE() <<
"Query exec error: " << query.lastQuery();
231 TRACE() <<
"Query exec error: " << query.lastQuery();
245 TRACE() <<
"Could not start transaction";
250 foreach (QString queryStr, queryList) {
251 TRACE() << QString::fromLatin1(
"TRANSACT Query [%1]").arg(queryStr);
252 QSqlQuery query =
exec(queryStr);
261 TRACE() <<
"Commit SUCCEEDED.";
267 TRACE() <<
"Transactional exec FAILED!";
278 if (sqlError.isValid()) {
279 if (sqlError.type() == QSqlError::ConnectionError) {
280 m_lastError.setType(SignOn::CredentialsDBError::ConnectionError);
282 m_lastError.setType(SignOn::CredentialsDBError::StatementError);
284 m_lastError.setText(sqlError.text());
292 if (!error.isValid())
293 return QLatin1String(
"SQL Error invalid.");
296 QTextStream stream(&text);
297 stream <<
"SQL error description:";
298 stream <<
"\n\tType: ";
301 switch (error.type()) {
303 case QSqlError::ConnectionError: errType =
"ConnectionError";
break;
304 case QSqlError::StatementError: errType =
"StatementError";
break;
305 case QSqlError::TransactionError: errType =
"TransactionError";
break;
308 default: errType =
"UnknownError";
311 stream <<
"\n\tDatabase text: " << error.databaseText();
312 stream <<
"\n\tDriver text: " << error.driverText();
313 stream <<
"\n\tNumber: " << error.number();
321 if (!query.prepare(query_str))
322 TRACE() <<
"Query prepare warning: " << query.lastQuery();
329 QSqlQuery query =
exec(q);
331 while (query.next()) {
332 list.append(query.value(0).toString());
338 QStringList MetaDataDB::tableUpdates2()
340 QStringList tableUpdates = QStringList()
341 << QString::fromLatin1(
343 "(rowid INTEGER PRIMARY KEY AUTOINCREMENT," 344 "identity_id INTEGER CONSTRAINT fk_identity_id REFERENCES CREDENTIALS(id) ON DELETE CASCADE," 345 "token_id INTEGER CONSTRAINT fk_token_id REFERENCES TOKENS(id) ON DELETE CASCADE)")
347 << QString::fromLatin1(
349 "CREATE TRIGGER fki_OWNER_token_id_TOKENS_id " 350 "BEFORE INSERT ON [OWNER] " 351 "FOR EACH ROW BEGIN " 352 " SELECT RAISE(ROLLBACK, 'insert on table OWNER violates foreign key constraint fki_OWNER_token_id_TOKENS_id') " 353 " WHERE NEW.token_id IS NOT NULL AND (SELECT id FROM TOKENS WHERE id = NEW.token_id) IS NULL; " 356 << QString::fromLatin1(
358 "CREATE TRIGGER fku_OWNER_token_id_TOKENS_id " 359 "BEFORE UPDATE ON [OWNER] " 360 "FOR EACH ROW BEGIN " 361 " SELECT RAISE(ROLLBACK, 'update on table OWNER violates foreign key constraint fku_OWNER_token_id_TOKENS_id') " 362 " WHERE NEW.token_id IS NOT NULL AND (SELECT id FROM TOKENS WHERE id = NEW.token_id) IS NULL; " 365 << QString::fromLatin1(
367 "CREATE TRIGGER fkdc_OWNER_token_id_TOKENS_id " 368 "BEFORE DELETE ON TOKENS " 369 "FOR EACH ROW BEGIN " 370 " DELETE FROM OWNER WHERE OWNER.token_id = OLD.id; " 380 QStringList createTableQuery = QStringList()
381 << QString::fromLatin1(
382 "CREATE TABLE CREDENTIALS" 383 "(id INTEGER PRIMARY KEY AUTOINCREMENT," 388 << QString::fromLatin1(
389 "CREATE TABLE METHODS" 390 "(id INTEGER PRIMARY KEY AUTOINCREMENT," 391 "method TEXT UNIQUE)")
392 << QString::fromLatin1(
393 "CREATE TABLE MECHANISMS" 394 "(id INTEGER PRIMARY KEY AUTOINCREMENT," 395 "mechanism TEXT UNIQUE)")
396 << QString::fromLatin1(
397 "CREATE TABLE TOKENS" 398 "(id INTEGER PRIMARY KEY AUTOINCREMENT," 399 "token TEXT UNIQUE)")
400 << QString::fromLatin1(
401 "CREATE TABLE REALMS" 402 "(identity_id INTEGER CONSTRAINT fk_identity_id REFERENCES CREDENTIALS(id) ON DELETE CASCADE," 405 "PRIMARY KEY (identity_id, realm, hostname))")
406 << QString::fromLatin1(
408 "(rowid INTEGER PRIMARY KEY AUTOINCREMENT," 409 "identity_id INTEGER CONSTRAINT fk_identity_id REFERENCES CREDENTIALS(id) ON DELETE CASCADE," 410 "method_id INTEGER CONSTRAINT fk_method_id REFERENCES METHODS(id) ON DELETE CASCADE," 411 "mechanism_id INTEGER CONSTRAINT fk_mechanism_id REFERENCES MECHANISMS(id) ON DELETE CASCADE," 412 "token_id INTEGER CONSTRAINT fk_token_id REFERENCES TOKENS(id) ON DELETE CASCADE)")
413 << QString::fromLatin1(
415 "(identity_id INTEGER CONSTRAINT fk_identity_id REFERENCES CREDENTIALS(id) ON DELETE CASCADE," 416 "token_id INTEGER CONSTRAINT fk_token_id REFERENCES TOKENS(id) ON DELETE CASCADE," 418 "PRIMARY KEY (identity_id, token_id, ref))")
425 << QString::fromLatin1(
427 "CREATE TRIGGER fki_REALMS_identity_id_CREDENTIALS_id " 428 "BEFORE INSERT ON [REALMS] " 429 "FOR EACH ROW BEGIN " 430 " SELECT RAISE(ROLLBACK, 'insert on table REALMS violates foreign key constraint fki_REALMS_identity_id_CREDENTIALS_id') " 431 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM CREDENTIALS WHERE id = NEW.identity_id) IS NULL; " 434 << QString::fromLatin1(
436 "CREATE TRIGGER fku_REALMS_identity_id_CREDENTIALS_id " 437 "BEFORE UPDATE ON [REALMS] " 438 "FOR EACH ROW BEGIN " 439 " SELECT RAISE(ROLLBACK, 'update on table REALMS violates foreign key constraint fku_REALMS_identity_id_CREDENTIALS_id') " 440 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM CREDENTIALS WHERE id = NEW.identity_id) IS NULL; " 443 << QString::fromLatin1(
445 "CREATE TRIGGER fkdc_REALMS_identity_id_CREDENTIALS_id " 446 "BEFORE DELETE ON CREDENTIALS " 447 "FOR EACH ROW BEGIN " 448 " DELETE FROM REALMS WHERE REALMS.identity_id = OLD.id; " 451 << QString::fromLatin1(
453 "CREATE TRIGGER fki_ACL_identity_id_CREDENTIALS_id " 454 "BEFORE INSERT ON [ACL] " 455 "FOR EACH ROW BEGIN " 456 " SELECT RAISE(ROLLBACK, 'insert on table ACL violates foreign key constraint fki_ACL_identity_id_CREDENTIALS_id') " 457 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM CREDENTIALS WHERE id = NEW.identity_id) IS NULL; " 460 << QString::fromLatin1(
462 "CREATE TRIGGER fku_ACL_identity_id_CREDENTIALS_id " 463 "BEFORE UPDATE ON [ACL] " 464 "FOR EACH ROW BEGIN " 465 " SELECT RAISE(ROLLBACK, 'update on table ACL violates foreign key constraint fku_ACL_identity_id_CREDENTIALS_id') " 466 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM CREDENTIALS WHERE id = NEW.identity_id) IS NULL; " 469 << QString::fromLatin1(
471 "CREATE TRIGGER fkdc_ACL_identity_id_CREDENTIALS_id " 472 "BEFORE DELETE ON CREDENTIALS " 473 "FOR EACH ROW BEGIN " 474 " DELETE FROM ACL WHERE ACL.identity_id = OLD.id; " 477 << QString::fromLatin1(
479 "CREATE TRIGGER fki_ACL_method_id_METHODS_id " 480 "BEFORE INSERT ON [ACL] " 481 "FOR EACH ROW BEGIN " 482 " SELECT RAISE(ROLLBACK, 'insert on table ACL violates foreign key constraint fki_ACL_method_id_METHODS_id') " 483 " WHERE NEW.method_id IS NOT NULL AND (SELECT id FROM METHODS WHERE id = NEW.method_id) IS NULL; " 486 << QString::fromLatin1(
488 "CREATE TRIGGER fku_ACL_method_id_METHODS_id " 489 "BEFORE UPDATE ON [ACL] " 490 "FOR EACH ROW BEGIN " 491 " SELECT RAISE(ROLLBACK, 'update on table ACL violates foreign key constraint fku_ACL_method_id_METHODS_id') " 492 " WHERE NEW.method_id IS NOT NULL AND (SELECT id FROM METHODS WHERE id = NEW.method_id) IS NULL; " 495 << QString::fromLatin1(
497 "CREATE TRIGGER fkdc_ACL_method_id_METHODS_id " 498 "BEFORE DELETE ON METHODS " 499 "FOR EACH ROW BEGIN " 500 " DELETE FROM ACL WHERE ACL.method_id = OLD.id; " 503 << QString::fromLatin1(
505 "CREATE TRIGGER fki_ACL_mechanism_id_MECHANISMS_id " 506 "BEFORE INSERT ON [ACL] " 507 "FOR EACH ROW BEGIN " 508 " SELECT RAISE(ROLLBACK, 'insert on table ACL violates foreign key constraint fki_ACL_mechanism_id_MECHANISMS_id') " 509 " WHERE NEW.mechanism_id IS NOT NULL AND (SELECT id FROM MECHANISMS WHERE id = NEW.mechanism_id) IS NULL; " 512 << QString::fromLatin1(
514 "CREATE TRIGGER fku_ACL_mechanism_id_MECHANISMS_id " 515 "BEFORE UPDATE ON [ACL] " 516 "FOR EACH ROW BEGIN " 517 " SELECT RAISE(ROLLBACK, 'update on table ACL violates foreign key constraint fku_ACL_mechanism_id_MECHANISMS_id') " 518 " WHERE NEW.mechanism_id IS NOT NULL AND (SELECT id FROM MECHANISMS WHERE id = NEW.mechanism_id) IS NULL; " 521 << QString::fromLatin1(
523 "CREATE TRIGGER fkdc_ACL_mechanism_id_MECHANISMS_id " 524 "BEFORE DELETE ON MECHANISMS " 525 "FOR EACH ROW BEGIN " 526 " DELETE FROM ACL WHERE ACL.mechanism_id = OLD.id; " 529 << QString::fromLatin1(
531 "CREATE TRIGGER fki_ACL_token_id_TOKENS_id " 532 "BEFORE INSERT ON [ACL] " 533 "FOR EACH ROW BEGIN " 534 " SELECT RAISE(ROLLBACK, 'insert on table ACL violates foreign key constraint fki_ACL_token_id_TOKENS_id') " 535 " WHERE NEW.token_id IS NOT NULL AND (SELECT id FROM TOKENS WHERE id = NEW.token_id) IS NULL; " 538 << QString::fromLatin1(
540 "CREATE TRIGGER fku_ACL_token_id_TOKENS_id " 541 "BEFORE UPDATE ON [ACL] " 542 "FOR EACH ROW BEGIN " 543 " SELECT RAISE(ROLLBACK, 'update on table ACL violates foreign key constraint fku_ACL_token_id_TOKENS_id') " 544 " WHERE NEW.token_id IS NOT NULL AND (SELECT id FROM TOKENS WHERE id = NEW.token_id) IS NULL; " 547 << QString::fromLatin1(
549 "CREATE TRIGGER fkdc_ACL_token_id_TOKENS_id " 550 "BEFORE DELETE ON TOKENS " 551 "FOR EACH ROW BEGIN " 552 " DELETE FROM ACL WHERE ACL.token_id = OLD.id; " 555 << QString::fromLatin1(
557 "CREATE TRIGGER fki_REFS_identity_id_CREDENTIALS_id " 558 "BEFORE INSERT ON [REFS] " 559 "FOR EACH ROW BEGIN " 560 " SELECT RAISE(ROLLBACK, 'insert on table REFS violates foreign key constraint fki_REFS_identity_id_CREDENTIALS_id') " 561 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM CREDENTIALS WHERE id = NEW.identity_id) IS NULL; " 564 << QString::fromLatin1(
566 "CREATE TRIGGER fku_REFS_identity_id_CREDENTIALS_id " 567 "BEFORE UPDATE ON [REFS] " 568 "FOR EACH ROW BEGIN " 569 " SELECT RAISE(ROLLBACK, 'update on table REFS violates foreign key constraint fku_REFS_identity_id_CREDENTIALS_id') " 570 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM CREDENTIALS WHERE id = NEW.identity_id) IS NULL; " 573 << QString::fromLatin1(
575 "CREATE TRIGGER fkdc_REFS_identity_id_CREDENTIALS_id " 576 "BEFORE DELETE ON CREDENTIALS " 577 "FOR EACH ROW BEGIN " 578 " DELETE FROM REFS WHERE REFS.identity_id = OLD.id; " 581 << QString::fromLatin1(
583 "CREATE TRIGGER fki_REFS_token_id_TOKENS_id " 584 "BEFORE INSERT ON [REFS] " 585 "FOR EACH ROW BEGIN " 586 " SELECT RAISE(ROLLBACK, 'insert on table REFS violates foreign key constraint fki_REFS_token_id_TOKENS_id') " 587 " WHERE NEW.token_id IS NOT NULL AND (SELECT id FROM TOKENS WHERE id = NEW.token_id) IS NULL; " 590 << QString::fromLatin1(
592 "CREATE TRIGGER fku_REFS_token_id_TOKENS_id " 593 "BEFORE UPDATE ON [REFS] " 594 "FOR EACH ROW BEGIN " 595 " SELECT RAISE(ROLLBACK, 'update on table REFS violates foreign key constraint fku_REFS_token_id_TOKENS_id') " 596 " WHERE NEW.token_id IS NOT NULL AND (SELECT id FROM TOKENS WHERE id = NEW.token_id) IS NULL; " 599 << QString::fromLatin1(
601 "CREATE TRIGGER fkdc_REFS_token_id_TOKENS_id " 602 "BEFORE DELETE ON TOKENS " 603 "FOR EACH ROW BEGIN " 604 " DELETE FROM REFS WHERE REFS.token_id = OLD.id; " 611 createTableQuery << tableUpdates2();
613 foreach (QString createTable, createTableQuery) {
614 QSqlQuery query =
exec(createTable);
616 TRACE() <<
"Error occurred while creating the database.";
622 TRACE() <<
"Creation successful";
633 TRACE() <<
"Upgrading from version < 1 not supported. Clearing DB";
637 QFile::remove(fileName);
638 m_database = QSqlDatabase(QSqlDatabase::addDatabase(driver,
650 QStringList createTableQuery = tableUpdates2();
651 foreach (QString createTable, createTableQuery) {
652 QSqlQuery query =
exec(createTable);
654 TRACE() <<
"Error occurred while inseting new tables.";
660 TRACE() <<
"Table insert successful";
663 QSqlQuery ownerInsert =
exec(
S(
"INSERT OR IGNORE INTO OWNER " 664 "(identity_id, token_id) " 665 " SELECT identity_id, token_id FROM ACL"));
667 BLAME() <<
"Table copy failed.";
681 if (securityToken.isEmpty()) {
683 QString::fromLatin1(
"SELECT DISTINCT METHODS.method FROM " 684 "( ACL JOIN METHODS ON ACL.method_id = METHODS.id ) " 685 "WHERE ACL.identity_id = '%1'").arg(
id)
690 q.prepare(
S(
"SELECT DISTINCT METHODS.method FROM " 691 "( ACL JOIN METHODS ON ACL.method_id = METHODS.id) " 692 "WHERE ACL.identity_id = :id AND ACL.token_id = " 693 "(SELECT id FROM TOKENS where token = :token)"));
694 q.bindValue(
S(
":id"),
id);
695 q.bindValue(
S(
":token"), securityToken);
703 TRACE() <<
"method:" << method;
706 q.prepare(
S(
"SELECT id FROM METHODS WHERE method = :method"));
707 q.bindValue(
S(
":method"), method);
710 TRACE() <<
"No result or invalid method query.";
714 return q.value(0).toUInt();
721 query_str = QString::fromLatin1(
722 "SELECT caption, username, flags, type " 723 "FROM credentials WHERE id = %1").arg(
id);
724 QSqlQuery query =
exec(query_str);
726 if (!query.first()) {
727 TRACE() <<
"No result or invalid credentials query.";
731 QString caption = query.value(0).toString();
732 QString
username = query.value(1).toString();
733 int flags = query.value(2).toInt();
737 if (isUserNameSecret) username = QString();
738 int type = query.value(3).toInt();
742 QString::fromLatin1(
"SELECT realm FROM REALMS " 743 "WHERE identity_id = %1").arg(
id));
746 QString::fromLatin1(
"SELECT token FROM TOKENS " 748 "(SELECT token_id FROM OWNER WHERE identity_id = '%1' )")
751 query_str = QString::fromLatin1(
"SELECT token FROM TOKENS " 753 "(SELECT token_id FROM ACL WHERE identity_id = '%1' )")
755 query =
exec(query_str);
756 QStringList securityTokens;
757 while (query.next()) {
758 securityTokens.append(query.value(0).toString());
762 query_str = QString::fromLatin1(
763 "SELECT DISTINCT ACL.method_id, METHODS.method FROM " 764 "( ACL JOIN METHODS ON ACL.method_id = METHODS.id ) " 765 "WHERE ACL.identity_id = '%1'").arg(
id);
766 query =
exec(query_str);
767 while (query.next()) {
769 QString::fromLatin1(
"SELECT DISTINCT MECHANISMS.mechanism FROM " 770 "( MECHANISMS JOIN ACL " 771 "ON ACL.mechanism_id = MECHANISMS.id ) " 772 "WHERE ACL.method_id = '%1' AND ACL.identity_id = '%2' ")
773 .arg(query.value(0).toInt()).arg(
id));
774 methods.insert(query.value(1).toString(), mechanisms);
783 if (!isUserNameSecret)
805 QString queryStr(QString::fromLatin1(
"SELECT id FROM credentials"));
809 queryStr += QString::fromLatin1(
" ORDER BY id");
811 QSqlQuery query =
exec(queryStr);
813 TRACE() <<
"Error occurred while fetching credentials from database.";
817 while (query.next()) {
831 TRACE() <<
"Could not start transaction. Error inserting credentials.";
835 quint32
id = updateCredentials(info);
844 if (!updateRealms(
id, info.
realms(), info.
isNew())) {
845 TRACE() <<
"Error in updating realms";
853 tokenInsert.prepare(
S(
"INSERT OR IGNORE INTO TOKENS (token) " 854 "VALUES ( :token )"));
855 tokenInsert.bindValue(
S(
":token"), token);
859 foreach (QString token, info.
ownerList()) {
860 if (!token.isEmpty()) {
862 tokenInsert.prepare(
S(
"INSERT OR IGNORE INTO TOKENS (token) " 863 "VALUES ( :token )"));
864 tokenInsert.bindValue(
S(
":token"), token);
871 QString queryStr = QString::fromLatin1(
872 "DELETE FROM ACL WHERE " 873 "identity_id = '%1'")
875 QSqlQuery insertQuery =
exec(queryStr);
878 queryStr = QString::fromLatin1(
879 "DELETE FROM OWNER WHERE " 880 "identity_id = '%1'")
882 insertQuery =
exec(queryStr);
887 QMapIterator<QString, QStringList> it(info.
methods());
888 while (it.hasNext()) {
892 foreach (QString mech, it.value()) {
894 aclInsert.prepare(
S(
"INSERT OR REPLACE INTO ACL " 895 "(identity_id, method_id, mechanism_id, token_id) " 897 "( SELECT id FROM METHODS WHERE method = :method )," 898 "( SELECT id FROM MECHANISMS WHERE mechanism= :mech ), " 899 "( SELECT id FROM TOKENS WHERE token = :token ))"));
900 aclInsert.bindValue(
S(
":id"),
id);
901 aclInsert.bindValue(
S(
":method"), it.key());
902 aclInsert.bindValue(
S(
":mech"), mech);
903 aclInsert.bindValue(
S(
":token"), token);
907 if (it.value().isEmpty()) {
909 aclInsert.prepare(
S(
"INSERT OR REPLACE INTO ACL (identity_id, method_id, token_id) " 911 "( SELECT id FROM METHODS WHERE method = :method )," 912 "( SELECT id FROM TOKENS WHERE token = :token ))"));
913 aclInsert.bindValue(
S(
":id"),
id);
914 aclInsert.bindValue(
S(
":method"), it.key());
915 aclInsert.bindValue(
S(
":token"), token);
920 foreach (QString mech, it.value()) {
922 aclInsert.prepare(
S(
"INSERT OR REPLACE INTO ACL " 923 "(identity_id, method_id, mechanism_id) " 925 "( SELECT id FROM METHODS WHERE method = :method )," 926 "( SELECT id FROM MECHANISMS WHERE mechanism= :mech )" 928 aclInsert.bindValue(
S(
":id"),
id);
929 aclInsert.bindValue(
S(
":method"), it.key());
930 aclInsert.bindValue(
S(
":mech"), mech);
934 if (it.value().isEmpty()) {
936 aclInsert.prepare(
S(
"INSERT OR REPLACE INTO ACL (identity_id, method_id) " 938 "( SELECT id FROM METHODS WHERE method = :method )" 940 aclInsert.bindValue(
S(
":id"),
id);
941 aclInsert.bindValue(
S(
":method"), it.key());
947 if (info.
methods().isEmpty()) {
950 aclInsert.prepare(
S(
"INSERT OR REPLACE INTO ACL " 951 "(identity_id, token_id) " 953 "( SELECT id FROM TOKENS WHERE token = :token ))"));
954 aclInsert.bindValue(
S(
":id"),
id);
955 aclInsert.bindValue(
S(
":token"), token);
961 foreach (QString token, info.
ownerList()) {
962 if (!token.isEmpty()) {
964 ownerInsert.prepare(
S(
"INSERT OR REPLACE INTO OWNER " 965 "(identity_id, token_id) " 967 "( SELECT id FROM TOKENS WHERE token = :token ))"));
968 ownerInsert.bindValue(
S(
":id"),
id);
969 ownerInsert.bindValue(
S(
":token"), token);
978 TRACE() <<
"Credentials insertion failed.";
987 QStringList queries = QStringList()
988 << QString::fromLatin1(
989 "DELETE FROM CREDENTIALS WHERE id = %1").arg(
id)
990 << QString::fromLatin1(
991 "DELETE FROM ACL WHERE identity_id = %1").arg(
id)
992 << QString::fromLatin1(
993 "DELETE FROM REALMS WHERE identity_id = %1").arg(
id)
994 << QString::fromLatin1(
995 "DELETE FROM owner WHERE identity_id = %1").arg(
id);
1004 QStringList clearCommands = QStringList()
1005 << QLatin1String(
"DELETE FROM CREDENTIALS")
1006 << QLatin1String(
"DELETE FROM METHODS")
1007 << QLatin1String(
"DELETE FROM MECHANISMS")
1008 << QLatin1String(
"DELETE FROM ACL")
1009 << QLatin1String(
"DELETE FROM REALMS")
1010 << QLatin1String(
"DELETE FROM TOKENS")
1011 << QLatin1String(
"DELETE FROM OWNER");
1018 return queryList(QString::fromLatin1(
"SELECT token FROM TOKENS " 1020 "(SELECT token_id FROM ACL WHERE identity_id = '%1' )")
1026 return queryList(QString::fromLatin1(
"SELECT token FROM TOKENS " 1028 "(SELECT token_id FROM OWNER WHERE identity_id = '%1' )")
1033 const QString &token,
1034 const QString &reference)
1037 TRACE() <<
"Could not start transaction. Error inserting data.";
1041 TRACE() <<
"Storing:" <<
id <<
", " << token <<
", " << reference;
1046 QSqlQuery tokenInsert =
newQuery();
1047 tokenInsert.prepare(
S(
"INSERT OR IGNORE INTO TOKENS (token) " 1048 "VALUES ( :token )"));
1049 tokenInsert.bindValue(
S(
":token"), token);
1056 refsInsert.prepare(
S(
"INSERT OR REPLACE INTO REFS " 1057 "(identity_id, token_id, ref) " 1059 "( SELECT id FROM TOKENS WHERE token = :token )," 1062 refsInsert.bindValue(
S(
":id"),
id);
1063 refsInsert.bindValue(
S(
":token"), token);
1064 refsInsert.bindValue(
S(
":reference"), reference);
1071 TRACE() <<
"Data insertion ok.";
1075 TRACE() <<
"Data insertion failed.";
1080 const QString &token,
1081 const QString &reference)
1083 TRACE() <<
"Removing:" <<
id <<
", " << token <<
", " << reference;
1085 QStringList refs = references(
id, token);
1088 if (!reference.isNull() && !refs.contains(reference))
1092 TRACE() <<
"Could not start transaction. Error removing data.";
1099 if (reference.isEmpty()) {
1100 refsDelete.prepare(
S(
"DELETE FROM REFS " 1101 "WHERE identity_id = :id AND " 1102 "token_id = ( SELECT id FROM TOKENS WHERE token = :token )"));
1103 refsDelete.bindValue(
S(
":id"),
id);
1104 refsDelete.bindValue(
S(
":token"), token);
1106 refsDelete.prepare(
S(
"DELETE FROM REFS " 1107 "WHERE identity_id = :id AND " 1108 "token_id = ( SELECT id FROM TOKENS WHERE token = :token ) " 1110 refsDelete.bindValue(
S(
":id"),
id);
1111 refsDelete.bindValue(
S(
":token"), token);
1112 refsDelete.bindValue(
S(
":ref"), reference);
1121 TRACE() <<
"Data delete ok.";
1125 TRACE() <<
"Data delete failed.";
1131 if (token.isEmpty())
1132 return queryList(QString::fromLatin1(
"SELECT ref FROM REFS " 1133 "WHERE identity_id = '%1'")
1136 q.prepare(
S(
"SELECT ref FROM REFS " 1137 "WHERE identity_id = :id AND " 1138 "token_id = (SELECT id FROM TOKENS WHERE token = :token )"));
1139 q.bindValue(
S(
":id"),
id);
1140 q.bindValue(
S(
":token"), token);
1148 if (methods.isEmpty())
return false;
1150 QMapIterator<QString, QStringList> it(methods);
1151 while (it.hasNext()) {
1153 QSqlQuery methodInsert =
newQuery();
1154 methodInsert.prepare(
S(
"INSERT OR IGNORE INTO METHODS (method) " 1155 "VALUES( :method )"));
1156 methodInsert.bindValue(
S(
":method"), it.key());
1160 foreach (QString mech, it.value()) {
1162 mechInsert.prepare(
S(
"INSERT OR IGNORE INTO MECHANISMS (mechanism) " 1163 "VALUES( :mech )"));
1164 mechInsert.bindValue(
S(
":mech"), mech);
1175 q.prepare(
S(
"INSERT INTO METHODS (method) VALUES(:method)"));
1176 q.bindValue(
S(
":method"), method);
1180 if (ok != 0) *ok =
false;
1183 return q.lastInsertId().toUInt(ok);
1196 if (!info.
isNew()) {
1197 TRACE() <<
"UPDATE:" << info.
id() ;
1198 q.prepare(
S(
"UPDATE CREDENTIALS SET caption = :caption, " 1199 "username = :username, " 1201 "type = :type WHERE id = :id"));
1202 q.bindValue(
S(
":id"), info.
id());
1204 TRACE() <<
"INSERT:" << info.
id();
1205 q.prepare(
S(
"INSERT INTO CREDENTIALS " 1206 "(caption, username, flags, type) " 1207 "VALUES(:caption, :username, :flags, :type)"));
1209 q.bindValue(
S(
":username"),
1211 q.bindValue(
S(
":caption"), info.
caption());
1212 q.bindValue(
S(
":flags"), flags);
1213 q.bindValue(
S(
":type"), info.
type());
1216 TRACE() <<
"Error occurred while updating crendentials";
1222 QVariant idVariant = q.lastInsertId();
1223 if (!idVariant.isValid()) {
1224 TRACE() <<
"Error occurred while inserting crendentials";
1227 id = idVariant.toUInt();
1235 bool MetaDataDB::updateRealms(quint32
id,
const QStringList &realms,
bool isNew)
1241 queryStr = QString::fromLatin1(
1242 "DELETE FROM REALMS WHERE identity_id = '%1'")
1249 q.prepare(
S(
"INSERT OR IGNORE INTO REALMS (identity_id, realm) " 1250 "VALUES (:id, :realm)"));
1251 foreach (QString realm, realms) {
1252 q.bindValue(
S(
":id"),
id);
1253 q.bindValue(
S(
":realm"), realm);
1262 CredentialsDB::ErrorMonitor::ErrorMonitor(
CredentialsDB *db)
1266 if (db->secretsStorage != 0)
1267 db->secretsStorage->clearError();
1271 CredentialsDB::ErrorMonitor::~ErrorMonitor()
1276 if (_db->_lastError.isValid())
1279 if (_db->secretsStorage != 0 &&
1280 _db->secretsStorage->lastError().isValid()) {
1281 _db->_lastError = _db->secretsStorage->lastError();
1285 _db->_lastError = _db->metaDataDB->lastError();
1291 SignOn::AbstractSecretsStorage *secretsStorage):
1292 secretsStorage(secretsStorage),
1296 noSecretsDB = SignOn::CredentialsDBError(
1297 QLatin1String(
"Secrets DB not opened"),
1298 SignOn::CredentialsDBError::ConnectionError);
1305 delete m_secretsCache;
1310 QSqlDatabase::removeDatabase(connectionName);
1316 return metaDataDB->
init();
1321 QVariantMap configuration;
1322 configuration.insert(QLatin1String(
"name"), secretsDbName);
1323 if (!secretsStorage->initialize(configuration)) {
1324 TRACE() <<
"SecretsStorage initialization failed: " <<
1325 secretsStorage->lastError().text();
1329 m_secretsCache->
storeToDB(secretsStorage);
1330 m_secretsCache->
clear();
1336 return secretsStorage != 0 && secretsStorage->isOpen();
1341 if (secretsStorage != 0) secretsStorage->close();
1350 const QString &securityToken)
1353 return metaDataDB->
methods(
id, securityToken);
1357 const QString &username,
1358 const QString &password)
1364 return secretsStorage->checkPassword(
id, username, password);
1366 return username == info.
userName() &&
1367 secretsStorage->checkPassword(
id, QString(), password);
1374 TRACE() <<
"id:" <<
id <<
"queryPassword:" << queryPassword;
1377 if (queryPassword && !info.
isNew()) {
1378 QString username, password;
1380 TRACE() <<
"Loading credentials from DB.";
1381 secretsStorage->loadCredentials(
id, username, password);
1383 TRACE() <<
"Looking up credentials from cache.";
1390 #ifdef DEBUG_ENABLED 1391 if (password.isEmpty()) {
1392 TRACE() <<
"Password is empty";
1418 if (
id == 0)
return id;
1421 QString password = info.
password();
1427 secretsStorage->updateCredentials(
id, userName, password);
1448 return secretsStorage->removeCredentials(
id) &&
1461 return secretsStorage->clear() && metaDataDB->
clear();
1466 TRACE() <<
"Loading:" <<
id <<
"," << method;
1469 if (
id == 0)
return QVariantMap();
1471 quint32 methodId = metaDataDB->
methodId(method);
1472 if (methodId == 0)
return QVariantMap();
1475 return secretsStorage->loadData(
id, methodId);
1477 TRACE() <<
"Looking up data from cache";
1478 return m_secretsCache->
lookupData(
id, methodId);
1483 const QVariantMap &data)
1485 TRACE() <<
"Storing:" <<
id <<
"," << method;
1488 if (
id == 0)
return false;
1490 quint32 methodId = metaDataDB->
methodId(method);
1491 if (methodId == 0) {
1499 return secretsStorage->storeData(
id, methodId, data);
1501 TRACE() <<
"Storing data into cache";
1502 m_secretsCache->
updateData(
id, methodId, data);
1509 TRACE() <<
"Removing:" <<
id <<
"," << method;
1513 if (
id == 0)
return false;
1516 if (!method.isEmpty()) {
1517 methodId = metaDataDB->
methodId(method);
1518 if (methodId == 0)
return false;
1523 return secretsStorage->removeData(
id, methodId);
1535 return metaDataDB->
ownerList(identityId);
1541 QStringList owners =
ownerList(identityId);
1542 return owners.count() ? owners.at(0) : QString();
1546 const QString &token,
1547 const QString &reference)
1554 const QString &token,
1555 const QString &reference)
bool removeData(const quint32 id, const QString &method=QString())
bool isUserNameSecret() const
QSqlQuery exec(const QString &query)
Executes a specific database query.
static QStringList supportedDrivers()
QStringList references(const quint32 id, const QString &token=QString())
void setRealms(const QStringList &realms)
bool lookupCredentials(quint32 id, QString &username, QString &password) const
Definition of the CredentialsDB object.
QStringList accessControlList() const
virtual ~SqlDatabase()
Destroys the SqlDatabase object, closing the database connection.
QStringList accessControlList(const quint32 identityId)
void setRefCount(int refCount)
bool storePassword() const
void setStorePassword(bool storePassword)
void setMethods(const MethodMap &methods)
quint32 insertCredentials(const SignonIdentityInfo &info)
quint32 updateCredentials(const SignonIdentityInfo &info)
Caches credentials or BLOB authentication data.
QStringList realms() const
SignOn::CredentialsDBError lastError() const
void credentialsUpdated(quint32 id)
void setCaption(const QString &caption)
bool storeData(const quint32 id, const QString &method, const QVariantMap &data)
bool addReference(const quint32 id, const QString &token, const QString &reference)
void storeToDB(SignOn::AbstractSecretsStorage *secretsStorage) const
QStringList ownerList() const
bool removeCredentials(const quint32 id)
QVariantMap loadData(const quint32 id, const QString &method)
SignOn::CredentialsDBError lastError() const
QString credentialsOwnerSecurityToken(const quint32 identityId)
void setPassword(const QString &password)
SignonIdentityInfo credentials(const quint32 id, bool queryPassword=true)
SqlDatabase(const QString &hostname, const QString &connectionName, int version)
Constructs a SqlDatabase object using the given hostname.
bool init()
Connects to the DB and if necessary creates the tables.
bool removeReference(const quint32 id, const QString &token, const QString &reference=QString())
#define RETURN_IF_NO_SECRETS_DB(retval)
bool connect()
Creates the database connection.
bool errorOccurred() const
bool openSecretsDB(const QString &secretsDbName)
This method will open the DB file containing the user secrets.
MethodMap methods() const
QVariantMap lookupData(quint32 id, quint32 method) const
void setAccessControlList(const QStringList &accessControlList)
bool transactionalExec(const QStringList &queryList)
Executes a specific database set of queryes (INSERTs, UPDATEs, DELETEs) in a transaction context (No ...
CredentialsDB(const QString &metaDataDbName, SignOn::AbstractSecretsStorage *secretsStorage)
void disconnect()
Destroys the database connection.
QStringList methods(const quint32 id, const QString &securityToken=QString())
Daemon side representation of identity information.
bool checkPassword(const quint32 id, const QString &username, const QString &password)
Manages the credentials I/O.
QSqlQuery newQuery() const
void updateCredentials(quint32 id, const QString &username, const QString &password, bool storePassword)
QStringList ownerList(const quint32 identityId)
QString connectionName() const
virtual bool updateDB(int version)
void setLastError(const QSqlError &sqlError)
void setUserName(const QString &userName)
static QString errorInfo(const QSqlError &error)
Serializes a SQL error into a string.
virtual bool createTables()=0
void updateData(quint32 id, quint32 method, const QVariantMap &data)
QStringList queryList(const QString &query_str)
void setUserNameSecret(bool secret)
void setValidated(bool validated)
void setOwnerList(const QStringList &owners)