31 #define INIT_ERROR() ErrorMonitor errorMonitor(this)
32 #define RETURN_IF_NO_SECRETS_DB(retval) \
33 if (!isSecretsDBOpen()) { \
34 TRACE() << "Secrets DB is not available"; \
35 _lastError = noSecretsDB; return retval; \
38 #define S(s) QLatin1String(s)
40 namespace SignonDaemonNS {
42 static const QString driver = QLatin1String(
"QSQLITE");
46 QString &password)
const
48 QHash<quint32, AuthCache>::const_iterator i;
51 if (i == m_cache.end())
return false;
53 username = i->m_username;
54 password = i->m_password;
60 return m_cache.value(
id).m_blobData.value(method);
64 const QString &username,
65 const QString &password,
71 credentials.m_username = username;
72 credentials.m_password = password;
73 credentials.m_storePassword = storePassword;
77 const QVariantMap &data)
82 credentials.m_blobData[method] = data;
88 if (m_cache.isEmpty())
return;
90 TRACE() <<
"Storing cached credentials into permanent storage";
92 QHash<quint32, AuthCache>::const_iterator i;
93 for (i = m_cache.constBegin();
94 i != m_cache.constEnd();
100 QString password = cache.m_storePassword ?
101 cache.m_password : QString();
102 if (!cache.m_username.isEmpty() || !password.isEmpty()) {
103 secretsStorage->updateCredentials(
id,
109 QHash<quint32, QVariantMap>::const_iterator j;
110 for (j = cache.m_blobData.constBegin();
111 j != cache.m_blobData.constEnd();
113 quint32 method = j.key();
114 secretsStorage->storeData(
id, method, j.value());
125 const QString &connectionName,
127 m_lastError(SignOn::CredentialsDBError()),
129 m_database(QSqlDatabase::addDatabase(driver, connectionName))
133 TRACE() <<
"DATABASE NAME [" << databaseName <<
"]";
149 TRACE() <<
"Database connection succeeded.";
152 TRACE() <<
"Creating SQL table structure...";
158 <<
".This could lead to data loss.";
160 TRACE() <<
"SQL table structure already created...";
162 QSqlQuery q =
exec(
S(
"PRAGMA user_version"));
163 int oldVersion = q.first() ? q.value(0).toInt() : 0;
173 TRACE() <<
"Update DB from version " << version <<
" to " <<
m_version;
174 exec(QString::fromLatin1(
"PRAGMA user_version = %1").arg(m_version));
181 TRACE() <<
"Could not open database connection.\n";
206 TRACE() <<
"Rollback failed, db data integrity could be compromised.";
213 if (!query.prepare(queryStr))
214 TRACE() <<
"Query prepare warning: " << query.lastQuery();
217 TRACE() <<
"Query exec error: " << query.lastQuery();
230 TRACE() <<
"Query exec error: " << query.lastQuery();
244 TRACE() <<
"Could not start transaction";
249 foreach (QString queryStr, queryList) {
250 TRACE() << QString::fromLatin1(
"TRANSACT Query [%1]").arg(queryStr);
251 QSqlQuery query =
exec(queryStr);
260 TRACE() <<
"Commit SUCCEEDED.";
266 TRACE() <<
"Transactional exec FAILED!";
277 if (sqlError.isValid()) {
278 if (sqlError.type() == QSqlError::ConnectionError) {
279 m_lastError.setType(SignOn::CredentialsDBError::ConnectionError);
281 m_lastError.setType(SignOn::CredentialsDBError::StatementError);
283 m_lastError.setText(sqlError.text());
291 if (!error.isValid())
292 return QLatin1String(
"SQL Error invalid.");
295 QTextStream stream(&text);
296 stream <<
"SQL error description:";
297 stream <<
"\n\tType: ";
300 switch (error.type()) {
302 case QSqlError::ConnectionError: errType =
"ConnectionError";
break;
303 case QSqlError::StatementError: errType =
"StatementError";
break;
304 case QSqlError::TransactionError: errType =
"TransactionError";
break;
307 default: errType =
"UnknownError";
310 stream <<
"\n\tDatabase text: " << error.databaseText();
311 stream <<
"\n\tDriver text: " << error.driverText();
312 stream <<
"\n\tNumber: " << error.number();
320 if (!query.prepare(query_str))
321 TRACE() <<
"Query prepare warning: " << query.lastQuery();
328 QSqlQuery query =
exec(q);
330 while (query.next()) {
331 list.append(query.value(0).toString());
337 QStringList MetaDataDB::tableUpdates2()
339 QStringList tableUpdates = QStringList()
340 << QString::fromLatin1(
342 "(rowid INTEGER PRIMARY KEY AUTOINCREMENT,"
343 "identity_id INTEGER CONSTRAINT fk_identity_id REFERENCES CREDENTIALS(id) ON DELETE CASCADE,"
344 "token_id INTEGER CONSTRAINT fk_token_id REFERENCES TOKENS(id) ON DELETE CASCADE)")
346 << QString::fromLatin1(
348 "CREATE TRIGGER fki_OWNER_token_id_TOKENS_id "
349 "BEFORE INSERT ON [OWNER] "
350 "FOR EACH ROW BEGIN "
351 " SELECT RAISE(ROLLBACK, 'insert on table OWNER violates foreign key constraint fki_OWNER_token_id_TOKENS_id') "
352 " WHERE NEW.token_id IS NOT NULL AND (SELECT id FROM TOKENS WHERE id = NEW.token_id) IS NULL; "
355 << QString::fromLatin1(
357 "CREATE TRIGGER fku_OWNER_token_id_TOKENS_id "
358 "BEFORE UPDATE ON [OWNER] "
359 "FOR EACH ROW BEGIN "
360 " SELECT RAISE(ROLLBACK, 'update on table OWNER violates foreign key constraint fku_OWNER_token_id_TOKENS_id') "
361 " WHERE NEW.token_id IS NOT NULL AND (SELECT id FROM TOKENS WHERE id = NEW.token_id) IS NULL; "
364 << QString::fromLatin1(
366 "CREATE TRIGGER fkdc_OWNER_token_id_TOKENS_id "
367 "BEFORE DELETE ON TOKENS "
368 "FOR EACH ROW BEGIN "
369 " DELETE FROM OWNER WHERE OWNER.token_id = OLD.id; "
379 QStringList createTableQuery = QStringList()
380 << QString::fromLatin1(
381 "CREATE TABLE CREDENTIALS"
382 "(id INTEGER PRIMARY KEY AUTOINCREMENT,"
387 << QString::fromLatin1(
388 "CREATE TABLE METHODS"
389 "(id INTEGER PRIMARY KEY AUTOINCREMENT,"
390 "method TEXT UNIQUE)")
391 << QString::fromLatin1(
392 "CREATE TABLE MECHANISMS"
393 "(id INTEGER PRIMARY KEY AUTOINCREMENT,"
394 "mechanism TEXT UNIQUE)")
395 << QString::fromLatin1(
396 "CREATE TABLE TOKENS"
397 "(id INTEGER PRIMARY KEY AUTOINCREMENT,"
398 "token TEXT UNIQUE)")
399 << QString::fromLatin1(
400 "CREATE TABLE REALMS"
401 "(identity_id INTEGER CONSTRAINT fk_identity_id REFERENCES CREDENTIALS(id) ON DELETE CASCADE,"
404 "PRIMARY KEY (identity_id, realm, hostname))")
405 << QString::fromLatin1(
407 "(rowid INTEGER PRIMARY KEY AUTOINCREMENT,"
408 "identity_id INTEGER CONSTRAINT fk_identity_id REFERENCES CREDENTIALS(id) ON DELETE CASCADE,"
409 "method_id INTEGER CONSTRAINT fk_method_id REFERENCES METHODS(id) ON DELETE CASCADE,"
410 "mechanism_id INTEGER CONSTRAINT fk_mechanism_id REFERENCES MECHANISMS(id) ON DELETE CASCADE,"
411 "token_id INTEGER CONSTRAINT fk_token_id REFERENCES TOKENS(id) ON DELETE CASCADE)")
412 << QString::fromLatin1(
414 "(identity_id INTEGER CONSTRAINT fk_identity_id REFERENCES CREDENTIALS(id) ON DELETE CASCADE,"
415 "token_id INTEGER CONSTRAINT fk_token_id REFERENCES TOKENS(id) ON DELETE CASCADE,"
417 "PRIMARY KEY (identity_id, token_id, ref))")
424 << QString::fromLatin1(
426 "CREATE TRIGGER fki_REALMS_identity_id_CREDENTIALS_id "
427 "BEFORE INSERT ON [REALMS] "
428 "FOR EACH ROW BEGIN "
429 " SELECT RAISE(ROLLBACK, 'insert on table REALMS violates foreign key constraint fki_REALMS_identity_id_CREDENTIALS_id') "
430 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM CREDENTIALS WHERE id = NEW.identity_id) IS NULL; "
433 << QString::fromLatin1(
435 "CREATE TRIGGER fku_REALMS_identity_id_CREDENTIALS_id "
436 "BEFORE UPDATE ON [REALMS] "
437 "FOR EACH ROW BEGIN "
438 " SELECT RAISE(ROLLBACK, 'update on table REALMS violates foreign key constraint fku_REALMS_identity_id_CREDENTIALS_id') "
439 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM CREDENTIALS WHERE id = NEW.identity_id) IS NULL; "
442 << QString::fromLatin1(
444 "CREATE TRIGGER fkdc_REALMS_identity_id_CREDENTIALS_id "
445 "BEFORE DELETE ON CREDENTIALS "
446 "FOR EACH ROW BEGIN "
447 " DELETE FROM REALMS WHERE REALMS.identity_id = OLD.id; "
450 << QString::fromLatin1(
452 "CREATE TRIGGER fki_ACL_identity_id_CREDENTIALS_id "
453 "BEFORE INSERT ON [ACL] "
454 "FOR EACH ROW BEGIN "
455 " SELECT RAISE(ROLLBACK, 'insert on table ACL violates foreign key constraint fki_ACL_identity_id_CREDENTIALS_id') "
456 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM CREDENTIALS WHERE id = NEW.identity_id) IS NULL; "
459 << QString::fromLatin1(
461 "CREATE TRIGGER fku_ACL_identity_id_CREDENTIALS_id "
462 "BEFORE UPDATE ON [ACL] "
463 "FOR EACH ROW BEGIN "
464 " SELECT RAISE(ROLLBACK, 'update on table ACL violates foreign key constraint fku_ACL_identity_id_CREDENTIALS_id') "
465 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM CREDENTIALS WHERE id = NEW.identity_id) IS NULL; "
468 << QString::fromLatin1(
470 "CREATE TRIGGER fkdc_ACL_identity_id_CREDENTIALS_id "
471 "BEFORE DELETE ON CREDENTIALS "
472 "FOR EACH ROW BEGIN "
473 " DELETE FROM ACL WHERE ACL.identity_id = OLD.id; "
476 << QString::fromLatin1(
478 "CREATE TRIGGER fki_ACL_method_id_METHODS_id "
479 "BEFORE INSERT ON [ACL] "
480 "FOR EACH ROW BEGIN "
481 " SELECT RAISE(ROLLBACK, 'insert on table ACL violates foreign key constraint fki_ACL_method_id_METHODS_id') "
482 " WHERE NEW.method_id IS NOT NULL AND (SELECT id FROM METHODS WHERE id = NEW.method_id) IS NULL; "
485 << QString::fromLatin1(
487 "CREATE TRIGGER fku_ACL_method_id_METHODS_id "
488 "BEFORE UPDATE ON [ACL] "
489 "FOR EACH ROW BEGIN "
490 " SELECT RAISE(ROLLBACK, 'update on table ACL violates foreign key constraint fku_ACL_method_id_METHODS_id') "
491 " WHERE NEW.method_id IS NOT NULL AND (SELECT id FROM METHODS WHERE id = NEW.method_id) IS NULL; "
494 << QString::fromLatin1(
496 "CREATE TRIGGER fkdc_ACL_method_id_METHODS_id "
497 "BEFORE DELETE ON METHODS "
498 "FOR EACH ROW BEGIN "
499 " DELETE FROM ACL WHERE ACL.method_id = OLD.id; "
502 << QString::fromLatin1(
504 "CREATE TRIGGER fki_ACL_mechanism_id_MECHANISMS_id "
505 "BEFORE INSERT ON [ACL] "
506 "FOR EACH ROW BEGIN "
507 " SELECT RAISE(ROLLBACK, 'insert on table ACL violates foreign key constraint fki_ACL_mechanism_id_MECHANISMS_id') "
508 " WHERE NEW.mechanism_id IS NOT NULL AND (SELECT id FROM MECHANISMS WHERE id = NEW.mechanism_id) IS NULL; "
511 << QString::fromLatin1(
513 "CREATE TRIGGER fku_ACL_mechanism_id_MECHANISMS_id "
514 "BEFORE UPDATE ON [ACL] "
515 "FOR EACH ROW BEGIN "
516 " SELECT RAISE(ROLLBACK, 'update on table ACL violates foreign key constraint fku_ACL_mechanism_id_MECHANISMS_id') "
517 " WHERE NEW.mechanism_id IS NOT NULL AND (SELECT id FROM MECHANISMS WHERE id = NEW.mechanism_id) IS NULL; "
520 << QString::fromLatin1(
522 "CREATE TRIGGER fkdc_ACL_mechanism_id_MECHANISMS_id "
523 "BEFORE DELETE ON MECHANISMS "
524 "FOR EACH ROW BEGIN "
525 " DELETE FROM ACL WHERE ACL.mechanism_id = OLD.id; "
528 << QString::fromLatin1(
530 "CREATE TRIGGER fki_ACL_token_id_TOKENS_id "
531 "BEFORE INSERT ON [ACL] "
532 "FOR EACH ROW BEGIN "
533 " SELECT RAISE(ROLLBACK, 'insert on table ACL violates foreign key constraint fki_ACL_token_id_TOKENS_id') "
534 " WHERE NEW.token_id IS NOT NULL AND (SELECT id FROM TOKENS WHERE id = NEW.token_id) IS NULL; "
537 << QString::fromLatin1(
539 "CREATE TRIGGER fku_ACL_token_id_TOKENS_id "
540 "BEFORE UPDATE ON [ACL] "
541 "FOR EACH ROW BEGIN "
542 " SELECT RAISE(ROLLBACK, 'update on table ACL violates foreign key constraint fku_ACL_token_id_TOKENS_id') "
543 " WHERE NEW.token_id IS NOT NULL AND (SELECT id FROM TOKENS WHERE id = NEW.token_id) IS NULL; "
546 << QString::fromLatin1(
548 "CREATE TRIGGER fkdc_ACL_token_id_TOKENS_id "
549 "BEFORE DELETE ON TOKENS "
550 "FOR EACH ROW BEGIN "
551 " DELETE FROM ACL WHERE ACL.token_id = OLD.id; "
554 << QString::fromLatin1(
556 "CREATE TRIGGER fki_REFS_identity_id_CREDENTIALS_id "
557 "BEFORE INSERT ON [REFS] "
558 "FOR EACH ROW BEGIN "
559 " SELECT RAISE(ROLLBACK, 'insert on table REFS violates foreign key constraint fki_REFS_identity_id_CREDENTIALS_id') "
560 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM CREDENTIALS WHERE id = NEW.identity_id) IS NULL; "
563 << QString::fromLatin1(
565 "CREATE TRIGGER fku_REFS_identity_id_CREDENTIALS_id "
566 "BEFORE UPDATE ON [REFS] "
567 "FOR EACH ROW BEGIN "
568 " SELECT RAISE(ROLLBACK, 'update on table REFS violates foreign key constraint fku_REFS_identity_id_CREDENTIALS_id') "
569 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM CREDENTIALS WHERE id = NEW.identity_id) IS NULL; "
572 << QString::fromLatin1(
574 "CREATE TRIGGER fkdc_REFS_identity_id_CREDENTIALS_id "
575 "BEFORE DELETE ON CREDENTIALS "
576 "FOR EACH ROW BEGIN "
577 " DELETE FROM REFS WHERE REFS.identity_id = OLD.id; "
580 << QString::fromLatin1(
582 "CREATE TRIGGER fki_REFS_token_id_TOKENS_id "
583 "BEFORE INSERT ON [REFS] "
584 "FOR EACH ROW BEGIN "
585 " SELECT RAISE(ROLLBACK, 'insert on table REFS violates foreign key constraint fki_REFS_token_id_TOKENS_id') "
586 " WHERE NEW.token_id IS NOT NULL AND (SELECT id FROM TOKENS WHERE id = NEW.token_id) IS NULL; "
589 << QString::fromLatin1(
591 "CREATE TRIGGER fku_REFS_token_id_TOKENS_id "
592 "BEFORE UPDATE ON [REFS] "
593 "FOR EACH ROW BEGIN "
594 " SELECT RAISE(ROLLBACK, 'update on table REFS violates foreign key constraint fku_REFS_token_id_TOKENS_id') "
595 " WHERE NEW.token_id IS NOT NULL AND (SELECT id FROM TOKENS WHERE id = NEW.token_id) IS NULL; "
598 << QString::fromLatin1(
600 "CREATE TRIGGER fkdc_REFS_token_id_TOKENS_id "
601 "BEFORE DELETE ON TOKENS "
602 "FOR EACH ROW BEGIN "
603 " DELETE FROM REFS WHERE REFS.token_id = OLD.id; "
610 createTableQuery << tableUpdates2();
612 foreach (QString createTable, createTableQuery) {
613 QSqlQuery query =
exec(createTable);
615 TRACE() <<
"Error occurred while creating the database.";
621 TRACE() <<
"Creation successful";
632 TRACE() <<
"Upgrading from version < 1 not supported. Clearing DB";
636 QFile::remove(fileName);
637 m_database = QSqlDatabase(QSqlDatabase::addDatabase(driver,
649 QStringList createTableQuery = tableUpdates2();
650 foreach (QString createTable, createTableQuery) {
651 QSqlQuery query =
exec(createTable);
653 TRACE() <<
"Error occurred while inseting new tables.";
659 TRACE() <<
"Table insert successful";
662 QSqlQuery ownerInsert =
exec(
S(
"INSERT OR IGNORE INTO OWNER "
663 "(identity_id, token_id) "
664 " SELECT identity_id, token_id FROM ACL"));
666 BLAME() <<
"Table copy failed.";
680 if (securityToken.isEmpty()) {
682 QString::fromLatin1(
"SELECT DISTINCT METHODS.method FROM "
683 "( ACL JOIN METHODS ON ACL.method_id = METHODS.id ) "
684 "WHERE ACL.identity_id = '%1'").arg(
id)
689 q.prepare(
S(
"SELECT DISTINCT METHODS.method FROM "
690 "( ACL JOIN METHODS ON ACL.method_id = METHODS.id) "
691 "WHERE ACL.identity_id = :id AND ACL.token_id = "
692 "(SELECT id FROM TOKENS where token = :token)"));
693 q.bindValue(
S(
":id"),
id);
694 q.bindValue(
S(
":token"), securityToken);
702 TRACE() <<
"method:" << method;
705 q.prepare(
S(
"SELECT id FROM METHODS WHERE method = :method"));
706 q.bindValue(
S(
":method"), method);
709 TRACE() <<
"No result or invalid method query.";
713 return q.value(0).toUInt();
720 query_str = QString::fromLatin1(
721 "SELECT caption, username, flags, type "
722 "FROM credentials WHERE id = %1").arg(
id);
723 QSqlQuery query =
exec(query_str);
725 if (!query.first()) {
726 TRACE() <<
"No result or invalid credentials query.";
730 QString caption = query.value(0).toString();
731 QString
username = query.value(1).toString();
732 int flags = query.value(2).toInt();
736 if (isUserNameSecret) username = QString();
737 int type = query.value(3).toInt();
741 QString::fromLatin1(
"SELECT realm FROM REALMS "
742 "WHERE identity_id = %1").arg(
id));
745 QString::fromLatin1(
"SELECT token FROM TOKENS "
747 "(SELECT token_id FROM OWNER WHERE identity_id = '%1' )")
750 query_str = QString::fromLatin1(
"SELECT token FROM TOKENS "
752 "(SELECT token_id FROM ACL WHERE identity_id = '%1' )")
754 query =
exec(query_str);
755 QStringList securityTokens;
756 while (query.next()) {
757 securityTokens.append(query.value(0).toString());
761 query_str = QString::fromLatin1(
762 "SELECT DISTINCT ACL.method_id, METHODS.method FROM "
763 "( ACL JOIN METHODS ON ACL.method_id = METHODS.id ) "
764 "WHERE ACL.identity_id = '%1'").arg(
id);
765 query =
exec(query_str);
766 while (query.next()) {
768 QString::fromLatin1(
"SELECT DISTINCT MECHANISMS.mechanism FROM "
769 "( MECHANISMS JOIN ACL "
770 "ON ACL.mechanism_id = MECHANISMS.id ) "
771 "WHERE ACL.method_id = '%1' AND ACL.identity_id = '%2' ")
772 .arg(query.value(0).toInt()).arg(
id));
773 methods.insert(query.value(1).toString(), mechanisms);
782 caption, methods, realms, securityTokens,
784 type, refCount, validated);
794 QList<SignonIdentityInfo> result;
796 QString queryStr(QString::fromLatin1(
"SELECT id FROM credentials"));
800 queryStr += QString::fromLatin1(
" ORDER BY id");
802 QSqlQuery query =
exec(queryStr);
804 TRACE() <<
"Error occurred while fetching credentials from database.";
808 while (query.next()) {
822 TRACE() <<
"Could not start transaction. Error inserting credentials.";
826 quint32
id = updateCredentials(info);
835 if (!updateRealms(
id, info.
realms(), info.
isNew())) {
836 TRACE() <<
"Error in updating realms";
844 tokenInsert.prepare(
S(
"INSERT OR IGNORE INTO TOKENS (token) "
845 "VALUES ( :token )"));
846 tokenInsert.bindValue(
S(
":token"), token);
850 foreach (QString token, info.
ownerList()) {
851 if (!token.isEmpty()) {
853 tokenInsert.prepare(
S(
"INSERT OR IGNORE INTO TOKENS (token) "
854 "VALUES ( :token )"));
855 tokenInsert.bindValue(
S(
":token"), token);
862 QString queryStr = QString::fromLatin1(
863 "DELETE FROM ACL WHERE "
864 "identity_id = '%1'")
866 QSqlQuery insertQuery =
exec(queryStr);
869 queryStr = QString::fromLatin1(
870 "DELETE FROM OWNER WHERE "
871 "identity_id = '%1'")
873 insertQuery =
exec(queryStr);
878 QMapIterator<QString, QStringList> it(info.
methods());
879 while (it.hasNext()) {
883 foreach (QString mech, it.value()) {
885 aclInsert.prepare(
S(
"INSERT OR REPLACE INTO ACL "
886 "(identity_id, method_id, mechanism_id, token_id) "
888 "( SELECT id FROM METHODS WHERE method = :method ),"
889 "( SELECT id FROM MECHANISMS WHERE mechanism= :mech ), "
890 "( SELECT id FROM TOKENS WHERE token = :token ))"));
891 aclInsert.bindValue(
S(
":id"),
id);
892 aclInsert.bindValue(
S(
":method"), it.key());
893 aclInsert.bindValue(
S(
":mech"), mech);
894 aclInsert.bindValue(
S(
":token"), token);
898 if (it.value().isEmpty()) {
900 aclInsert.prepare(
S(
"INSERT OR REPLACE INTO ACL (identity_id, method_id, token_id) "
902 "( SELECT id FROM METHODS WHERE method = :method ),"
903 "( SELECT id FROM TOKENS WHERE token = :token ))"));
904 aclInsert.bindValue(
S(
":id"),
id);
905 aclInsert.bindValue(
S(
":method"), it.key());
906 aclInsert.bindValue(
S(
":token"), token);
911 foreach (QString mech, it.value()) {
913 aclInsert.prepare(
S(
"INSERT OR REPLACE INTO ACL "
914 "(identity_id, method_id, mechanism_id) "
916 "( SELECT id FROM METHODS WHERE method = :method ),"
917 "( SELECT id FROM MECHANISMS WHERE mechanism= :mech )"
919 aclInsert.bindValue(
S(
":id"),
id);
920 aclInsert.bindValue(
S(
":method"), it.key());
921 aclInsert.bindValue(
S(
":mech"), mech);
925 if (it.value().isEmpty()) {
927 aclInsert.prepare(
S(
"INSERT OR REPLACE INTO ACL (identity_id, method_id) "
929 "( SELECT id FROM METHODS WHERE method = :method )"
931 aclInsert.bindValue(
S(
":id"),
id);
932 aclInsert.bindValue(
S(
":method"), it.key());
938 if (info.
methods().isEmpty()) {
941 aclInsert.prepare(
S(
"INSERT OR REPLACE INTO ACL "
942 "(identity_id, token_id) "
944 "( SELECT id FROM TOKENS WHERE token = :token ))"));
945 aclInsert.bindValue(
S(
":id"),
id);
946 aclInsert.bindValue(
S(
":token"), token);
952 foreach (QString token, info.
ownerList()) {
953 if (!token.isEmpty()) {
955 ownerInsert.prepare(
S(
"INSERT OR REPLACE INTO OWNER "
956 "(identity_id, token_id) "
958 "( SELECT id FROM TOKENS WHERE token = :token ))"));
959 ownerInsert.bindValue(
S(
":id"),
id);
960 ownerInsert.bindValue(
S(
":token"), token);
969 TRACE() <<
"Credentials insertion failed.";
978 QStringList queries = QStringList()
979 << QString::fromLatin1(
980 "DELETE FROM CREDENTIALS WHERE id = %1").arg(
id)
981 << QString::fromLatin1(
982 "DELETE FROM ACL WHERE identity_id = %1").arg(
id)
983 << QString::fromLatin1(
984 "DELETE FROM REALMS WHERE identity_id = %1").arg(
id)
985 << QString::fromLatin1(
986 "DELETE FROM owner WHERE identity_id = %1").arg(
id);
995 QStringList clearCommands = QStringList()
996 << QLatin1String(
"DELETE FROM CREDENTIALS")
997 << QLatin1String(
"DELETE FROM METHODS")
998 << QLatin1String(
"DELETE FROM MECHANISMS")
999 << QLatin1String(
"DELETE FROM ACL")
1000 << QLatin1String(
"DELETE FROM REALMS")
1001 << QLatin1String(
"DELETE FROM TOKENS")
1002 << QLatin1String(
"DELETE FROM OWNER");
1009 return queryList(QString::fromLatin1(
"SELECT token FROM TOKENS "
1011 "(SELECT token_id FROM ACL WHERE identity_id = '%1' )")
1017 return queryList(QString::fromLatin1(
"SELECT token FROM TOKENS "
1019 "(SELECT token_id FROM OWNER WHERE identity_id = '%1' )")
1024 const QString &token,
1025 const QString &reference)
1028 TRACE() <<
"Could not start transaction. Error inserting data.";
1032 TRACE() <<
"Storing:" <<
id <<
", " << token <<
", " << reference;
1037 QSqlQuery tokenInsert =
newQuery();
1038 tokenInsert.prepare(
S(
"INSERT OR IGNORE INTO TOKENS (token) "
1039 "VALUES ( :token )"));
1040 tokenInsert.bindValue(
S(
":token"), token);
1047 refsInsert.prepare(
S(
"INSERT OR REPLACE INTO REFS "
1048 "(identity_id, token_id, ref) "
1050 "( SELECT id FROM TOKENS WHERE token = :token ),"
1053 refsInsert.bindValue(
S(
":id"),
id);
1054 refsInsert.bindValue(
S(
":token"), token);
1055 refsInsert.bindValue(
S(
":reference"), reference);
1062 TRACE() <<
"Data insertion ok.";
1066 TRACE() <<
"Data insertion failed.";
1071 const QString &token,
1072 const QString &reference)
1074 TRACE() <<
"Removing:" <<
id <<
", " << token <<
", " << reference;
1079 if (!reference.isNull() && !refs.contains(reference))
1083 TRACE() <<
"Could not start transaction. Error removing data.";
1090 if (reference.isEmpty()) {
1091 refsDelete.prepare(
S(
"DELETE FROM REFS "
1092 "WHERE identity_id = :id AND "
1093 "token_id = ( SELECT id FROM TOKENS WHERE token = :token )"));
1094 refsDelete.bindValue(
S(
":id"),
id);
1095 refsDelete.bindValue(
S(
":token"), token);
1097 refsDelete.prepare(
S(
"DELETE FROM REFS "
1098 "WHERE identity_id = :id AND "
1099 "token_id = ( SELECT id FROM TOKENS WHERE token = :token ) "
1101 refsDelete.bindValue(
S(
":id"),
id);
1102 refsDelete.bindValue(
S(
":token"), token);
1103 refsDelete.bindValue(
S(
":ref"), reference);
1112 TRACE() <<
"Data delete ok.";
1116 TRACE() <<
"Data delete failed.";
1122 if (token.isEmpty())
1123 return queryList(QString::fromLatin1(
"SELECT ref FROM REFS "
1124 "WHERE identity_id = '%1'")
1127 q.prepare(
S(
"SELECT ref FROM REFS "
1128 "WHERE identity_id = :id AND "
1129 "token_id = (SELECT id FROM TOKENS WHERE token = :token )"));
1130 q.bindValue(
S(
":id"),
id);
1131 q.bindValue(
S(
":token"), token);
1135 bool MetaDataDB::insertMethods(QMap<QString, QStringList> methods)
1139 if (methods.isEmpty())
return false;
1141 QMapIterator<QString, QStringList> it(methods);
1142 while (it.hasNext()) {
1144 QSqlQuery methodInsert =
newQuery();
1145 methodInsert.prepare(
S(
"INSERT OR IGNORE INTO METHODS (method) "
1146 "VALUES( :method )"));
1147 methodInsert.bindValue(
S(
":method"), it.key());
1151 foreach (QString mech, it.value()) {
1153 mechInsert.prepare(
S(
"INSERT OR IGNORE INTO MECHANISMS (mechanism) "
1154 "VALUES( :mech )"));
1155 mechInsert.bindValue(
S(
":mech"), mech);
1166 q.prepare(
S(
"INSERT INTO METHODS (method) VALUES(:method)"));
1167 q.bindValue(
S(
":method"), method);
1171 if (ok != 0) *ok =
false;
1174 return q.lastInsertId().toUInt(ok);
1187 if (!info.
isNew()) {
1188 TRACE() <<
"UPDATE:" << info.
id() ;
1189 q.prepare(
S(
"UPDATE CREDENTIALS SET caption = :caption, "
1190 "username = :username, "
1192 "type = :type WHERE id = :id"));
1193 q.bindValue(
S(
":id"), info.
id());
1195 TRACE() <<
"INSERT:" << info.
id();
1196 q.prepare(
S(
"INSERT INTO CREDENTIALS "
1197 "(caption, username, flags, type) "
1198 "VALUES(:caption, :username, :flags, :type)"));
1200 q.bindValue(
S(
":username"),
1202 q.bindValue(
S(
":caption"), info.
caption());
1203 q.bindValue(
S(
":flags"), flags);
1204 q.bindValue(
S(
":type"), info.
type());
1207 TRACE() <<
"Error occurred while updating crendentials";
1213 QVariant idVariant = q.lastInsertId();
1214 if (!idVariant.isValid()) {
1215 TRACE() <<
"Error occurred while inserting crendentials";
1218 id = idVariant.toUInt();
1226 bool MetaDataDB::updateRealms(quint32
id,
const QStringList &realms,
bool isNew)
1232 queryStr = QString::fromLatin1(
1233 "DELETE FROM REALMS WHERE identity_id = '%1'")
1240 q.prepare(
S(
"INSERT OR IGNORE INTO REALMS (identity_id, realm) "
1241 "VALUES (:id, :realm)"));
1242 foreach (QString realm, realms) {
1243 q.bindValue(
S(
":id"),
id);
1244 q.bindValue(
S(
":realm"), realm);
1256 db->metaDataDB->clearError();
1257 if (db->secretsStorage != 0)
1258 db->secretsStorage->clearError();
1262 CredentialsDB::ErrorMonitor::~ErrorMonitor()
1267 if (_db->_lastError.isValid())
1270 if (_db->secretsStorage != 0 &&
1271 _db->secretsStorage->lastError().isValid()) {
1272 _db->_lastError = _db->secretsStorage->lastError();
1276 _db->_lastError = _db->metaDataDB->lastError();
1282 SignOn::AbstractSecretsStorage *secretsStorage):
1283 secretsStorage(secretsStorage),
1287 noSecretsDB = SignOn::CredentialsDBError(
1288 QLatin1String(
"Secrets DB not opened"),
1289 SignOn::CredentialsDBError::ConnectionError);
1296 delete m_secretsCache;
1301 QSqlDatabase::removeDatabase(connectionName);
1307 return metaDataDB->
init();
1312 QVariantMap configuration;
1313 configuration.insert(QLatin1String(
"name"), secretsDbName);
1314 if (!secretsStorage->initialize(configuration)) {
1315 TRACE() <<
"SecretsStorage initialization failed: " <<
1316 secretsStorage->lastError().text();
1320 m_secretsCache->
storeToDB(secretsStorage);
1321 m_secretsCache->
clear();
1327 return secretsStorage != 0 && secretsStorage->isOpen();
1332 if (secretsStorage != 0) secretsStorage->close();
1341 const QString &securityToken)
1344 return metaDataDB->
methods(
id, securityToken);
1348 const QString &username,
1349 const QString &password)
1355 return secretsStorage->checkPassword(
id, username, password);
1357 return username == info.
userName() &&
1358 secretsStorage->checkPassword(
id, QString(), password);
1365 TRACE() <<
"id:" <<
id <<
"queryPassword:" << queryPassword;
1368 if (queryPassword && !info.
isNew()) {
1369 QString username, password;
1371 TRACE() <<
"Loading credentials from DB.";
1372 secretsStorage->loadCredentials(
id, username, password);
1374 TRACE() <<
"Looking up credentials from cache.";
1381 #ifdef DEBUG_ENABLED
1382 if (password.isEmpty()) {
1383 TRACE() <<
"Password is empty";
1390 QList<SignonIdentityInfo>
1409 if (
id == 0)
return id;
1411 QString password = info.
password();
1417 secretsStorage->updateCredentials(
id, userName, password);
1435 return secretsStorage->removeCredentials(
id) &&
1448 return secretsStorage->clear() && metaDataDB->
clear();
1453 TRACE() <<
"Loading:" <<
id <<
"," << method;
1456 if (
id == 0)
return QVariantMap();
1458 quint32 methodId = metaDataDB->
methodId(method);
1459 if (methodId == 0)
return QVariantMap();
1462 return secretsStorage->loadData(
id, methodId);
1464 TRACE() <<
"Looking up data from cache";
1465 return m_secretsCache->
lookupData(
id, methodId);
1470 const QVariantMap &data)
1472 TRACE() <<
"Storing:" <<
id <<
"," << method;
1475 if (
id == 0)
return false;
1477 quint32 methodId = metaDataDB->
methodId(method);
1478 if (methodId == 0) {
1486 return secretsStorage->storeData(
id, methodId, data);
1488 TRACE() <<
"Storing data into cache";
1489 m_secretsCache->
updateData(
id, methodId, data);
1496 TRACE() <<
"Removing:" <<
id <<
"," << method;
1500 if (
id == 0)
return false;
1503 if (!method.isEmpty()) {
1504 methodId = metaDataDB->
methodId(method);
1505 if (methodId == 0)
return false;
1510 return secretsStorage->removeData(
id, methodId);
1522 return metaDataDB->
ownerList(identityId);
1528 QStringList owners =
ownerList(identityId);
1529 return owners.count() ? owners.at(0) : QString();
1533 const QString &token,
1534 const QString &reference)
1541 const QString &token,
1542 const QString &reference)