[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [KSecretService] 0e975cf: Move the user interface stuff to its own
From: Michael Leupold <lemma () confuego ! org>
Date: 2010-11-09 19:14:27
Message-ID: 20101109191427.D5400A60E1 () git ! kde ! org
[Download RAW message or body]
A ui/tests/dialoguifactorytest.h [License: GPL(v2)]
A ui/tests/dialoguifactorytest.cpp [License: GPL(v2)]
A ui/tests/CMakeLists.txt [License: Trivialfile.]
A ui/dialoguifactory.h [License: GPL(v2)]
A ui/dialoguifactory.cpp [License: GPL(v2)]
A ui/abstractuimanager.h [License: GPL(v2)]
A ui/abstractuijobs.h [License: GPL(v2)]
A ui/abstractuijobs.cpp [License: GPL(v2)]
A ui/CMakeLists.txt [License: Trivialfile.]
A frontend/tests/tempblockingjobs.h [License: GPL(v2)]
A frontend/tests/tempblockingjobs.cpp [License: GPL(v2)]
A frontend/tests/tempblockingitem.h [License: GPL(v2)]
A frontend/tests/tempblockingitem.cpp [License: GPL(v2)]
A frontend/tests/tempblockingcollectionmanager.h [License: GPL(v2)]
A frontend/tests/tempblockingcollectionmanager.cpp [License: GPL(v2)]
A frontend/tests/tempblockingcollection.h [License: GPL(v2)]
A frontend/tests/tempblockingcollection.cpp [License: GPL(v2)]
A frontend/tests/servicetest.h [License: GPL(v2)]
A frontend/tests/servicetest.cpp [License: GPL(v2)]
A frontend/tests/CMakeLists.txt [License: Trivialfile.]
A frontend/secret/session.h [License: GPL(v2)]
A frontend/secret/session.cpp [License: GPL(v2)]
A frontend/secret/service.h [License: GPL(v2)]
A frontend/secret/service.cpp [License: GPL(v2)]
A frontend/secret/secret.h [License: GPL(v2)]
A frontend/secret/secret.cpp [License: GPL(v2)]
A frontend/secret/prompt.h [License: GPL(v2)]
A frontend/secret/prompt.cpp [License: GPL(v2)]
A frontend/secret/item.h [License: GPL(v2)]
A frontend/secret/item.cpp [License: GPL(v2)]
A frontend/secret/collection.h [License: GPL(v2)]
A frontend/secret/collection.cpp [License: GPL(v2)]
A frontend/secret/adaptors/sessionadaptor.h [License: GPL(v2)]
A frontend/secret/adaptors/sessionadaptor.cpp [License: GPL(v2)]
A frontend/secret/adaptors/serviceadaptor.h [License: GPL(v2)]
A frontend/secret/adaptors/serviceadaptor.cpp [License: GPL(v2)]
A frontend/secret/adaptors/promptadaptor.h [License: GPL(v2)]
A frontend/secret/adaptors/promptadaptor.cpp [License: GPL(v2)]
A frontend/secret/adaptors/itemadaptor.h [License: GPL(v2)]
A frontend/secret/adaptors/itemadaptor.cpp [License: GPL(v2)]
A frontend/secret/adaptors/dbustypes.h [License: GPL(v2)]
A frontend/secret/adaptors/dbustypes.cpp [License: GPL(v2)]
A frontend/secret/adaptors/collectionadaptor.h [License: GPL(v2)]
A frontend/secret/adaptors/collectionadaptor.cpp [License: GPL(v2)]
A frontend/CMakeLists.txt [License: Trivialfile.]
commit 0e975cf34f7f4ce4ffc02a66916ce35faa82d5e7
Author: Michael Leupold <lemma@confuego.org>
Date: Sun Aug 29 11:18:05 2010 +0000
Move the user interface stuff to its own directory and its own static library for \
cleanup. Rename daemon to frontend and daemon/dbus to frontend/secret to account for \
what stuff actually is for.
svn path=/trunk/playground/base/ksecretservice/; revision=1169479
diff --git a/CMakeLists.txt b/CMakeLists.txt
index aa0d29e..929968e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,11 +17,12 @@ INCLUDE_DIRECTORIES (
KDE4_ADD_EXECUTABLE (ksecretserviced main.cpp)
TARGET_LINK_LIBRARIES (ksecretserviced
ksecretservicebackend
- ksecretservicedaemon
+ ksecretservicefrontend
ksecretservicelib
${KDE4_KDEUI_LIBS}
)
ADD_SUBDIRECTORY (backend)
-ADD_SUBDIRECTORY (daemon)
+ADD_SUBDIRECTORY (frontend)
ADD_SUBDIRECTORY (lib)
+ADD_SUBDIRECTORY (ui)
diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt
index a081412..f5e127b 100644
--- a/backend/CMakeLists.txt
+++ b/backend/CMakeLists.txt
@@ -18,9 +18,6 @@ SET (ksecretservice_backend_SRCS
ksecret/ksecretcollection.cpp
ksecret/ksecretitem.cpp
ksecret/ksecretjobs.cpp
- # user interface
- abstractuijobs.cpp
- dialoguifactory.cpp
)
KDE4_ADD_LIBRARY (ksecretservicebackend STATIC ${ksecretservice_backend_SRCS})
diff --git a/backend/abstractuijobs.cpp b/backend/abstractuijobs.cpp
deleted file mode 100644
index b8304b0..0000000
--- a/backend/abstractuijobs.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "abstractuijobs.h"
-#include "abstractuimanager.h"
-
-#include <QtCore/QEventLoop>
-#include <QtCore/QTimer>
-
-AbstractUiJob::AbstractUiJob(AbstractUiManager *manager) : QueuedJob(manager)
-{
-}
-
-AbstractUiJob::~AbstractUiJob()
-{
-}
-
-void AbstractUiJob::exec()
-{
- Q_ASSERT(false);
-}
-
-AbstractAskPasswordJob::AbstractAskPasswordJob(AbstractUiManager *manager,
- const QString &collection,
- bool secondTry)
- : AbstractUiJob(manager), m_collection(collection), m_secondTry(secondTry)
-{
-}
-
-AbstractAskPasswordJob::~AbstractAskPasswordJob()
-{
-}
-
-const QString &AbstractAskPasswordJob::collection() const
-{
- return m_collection;
-}
-
-bool AbstractAskPasswordJob::isSecondTry() const
-{
- return m_secondTry;
-}
-
-bool AbstractAskPasswordJob::result() const
-{
- return m_result;
-}
-
-const QCA::SecureArray &AbstractAskPasswordJob::password() const
-{
- return m_password;
-}
-
-void AbstractAskPasswordJob::setResult(bool result)
-{
- m_result = result;
-}
-
-void AbstractAskPasswordJob::setPassword(const QCA::SecureArray &password)
-{
- m_password = password;
-}
-
-#include "abstractuijobs.moc"
diff --git a/backend/abstractuijobs.h b/backend/abstractuijobs.h
deleted file mode 100644
index c9ad9aa..0000000
--- a/backend/abstractuijobs.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ABSTRACTUIJOBS_H
-#define ABSTRACTUIJOBS_H
-
-#include <queuedjob.h>
-#include <jobqueue.h>
-
-#include <QtCore/QQueue>
-#include <QtCrypto/QtCrypto>
-#include <kglobal.h>
-#include <kjob.h>
-
-class AbstractUiManager;
-
-/*
- * Abstract master-class of user interface jobs.
- */
-class AbstractUiJob : public QueuedJob
-{
- Q_OBJECT
-
-public:
- /**
- * Constructor.
- *
- * @param manager user interface job manager and parent object
- */
- explicit AbstractUiJob(AbstractUiManager *manager);
-
- /**
- * Destructor.
- */
- virtual ~AbstractUiJob();
-
- /**
- * Default implementation for user interface jobs. As a ui job can rarely be
- * run synchronously, exec() crashes.
- */
- virtual void exec();
-
-private:
- friend class UiJobManager;
-};
-
-/**
- * Job that asks a user for a password to unlock a collection.
- */
-class AbstractAskPasswordJob : public AbstractUiJob
-{
- Q_OBJECT
-
-public:
- /**
- * Constructor.
- *
- * @param manager ui job manager and parent object
- * @param collection label of the collection that should be opened
- * @param secondTry set to true if this is not the user's first try to enter
- * the password correctly
- */
- AbstractAskPasswordJob(AbstractUiManager *manager, const QString &collection,
- bool secondTry);
-
- /**
- * Destructor.
- */
- virtual ~AbstractAskPasswordJob();
-
- /**
- * Get the label of the collection that's about to be unlocked.
- */
- const QString &collection() const;
-
- /**
- * Check whether this is not the user's first try to enter the password.
- */
- bool isSecondTry() const;
-
- /**
- * Get the result of the operation.
- *
- * @return true if the user entered a password, false if not
- */
- bool result() const;
-
- /**
- * Get the password the user entered.
- *
- * @return the password entered by the user or an empty array if the user
- * didn't enter a password
- */
- const QCA::SecureArray &password() const;
-
-protected:
- /**
- * Set the result of the operation.
- *
- * @remarks this is used by derived classes
- * @param result result of the operation
- */
- void setResult(bool result);
-
- /**
- * Set the password entered by the user.
- *
- * @remarks This is used by derived classes
- * @param password password entered by the user
- */
- void setPassword(const QCA::SecureArray &password);
-
-private:
- QString m_collection; // name of the collection to be unlocked
- bool m_secondTry; // true if this is not the first try
- bool m_result; // the result of the operation
- QCA::SecureArray m_password; // the password entered by the user
-};
-
-#endif
diff --git a/backend/abstractuimanager.h b/backend/abstractuimanager.h
deleted file mode 100644
index 24e0d06..0000000
--- a/backend/abstractuimanager.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ABSTRACTUIMANAGER_H
-#define ABSTRACTUIMANAGER_H
-
-#include "abstractuijobs.h"
-
-/**
- * Abstract factory that provides means to create a user interface for the various
- * backend classes.
- *
- * This class can be reimplemented to provide a standard UI, a stripped-down UI
- * (probably for mobile devices) or even a bogus UI which can be used inside
- * unit-tests.
- */
-class AbstractUiManager : public JobQueue
-{
-public:
- virtual ~AbstractUiManager()
- {
- // TODO: clean-up
- };
-
- /**
- * Create a job for asking for user's password for unlocking a collection.
- *
- * @param collection label of the collection to be unlocked
- * @param secondTry set to true if the user already entered a wrong password \
before
- * @return a job which can be enqueued to ask the user for the unlock password
- */
- virtual AbstractAskPasswordJob *createAskPasswordJob(const QString &collection,
- bool secondTry) = 0;
-};
-
-#endif
diff --git a/backend/dialoguifactory.cpp b/backend/dialoguifactory.cpp
deleted file mode 100644
index ae12429..0000000
--- a/backend/dialoguifactory.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "dialoguifactory.h"
-
-#include <QtCore/QTimer>
-#include <kpassworddialog.h>
-
-AbstractAskPasswordJob* DialogUiFactory::createAskPasswordJob(const QString& \
collection,
- bool secondTry)
-{
- return new DialogAskPasswordJob(this, collection, secondTry);
-}
-
-DialogAskPasswordJob::DialogAskPasswordJob(AbstractUiManager *manager,
- const QString& collection,
- bool secondTry)
- : AbstractAskPasswordJob(manager, collection, secondTry), m_dialog(0)
-{
-}
-
-DialogAskPasswordJob::~DialogAskPasswordJob()
-{
-}
-
-void DialogAskPasswordJob::start()
-{
- Q_ASSERT(!m_dialog);
- // TODO: provide parent widget!
- m_dialog = new KPasswordDialog;
- m_dialog->setAttribute(Qt::WA_DeleteOnClose, true);
- // TODO: needs proper string
- m_dialog->setPrompt("Collection " + collection() + " wants password.");
- connect(m_dialog, SIGNAL(finished(int)), this, SLOT(dialogFinished(int)));
- m_dialog->show();
-}
-
-void DialogAskPasswordJob::dialogFinished(int result)
-{
- Q_ASSERT(m_dialog);
- if (result == QDialog::Accepted) {
- setPassword(QCA::SecureArray(m_dialog->password().toUtf8()));
- setResult(true);
- } else {
- setResult(false);
- }
- emitResult();
-}
-
-#include "dialoguifactory.moc"
diff --git a/backend/dialoguifactory.h b/backend/dialoguifactory.h
deleted file mode 100644
index f3c4dc0..0000000
--- a/backend/dialoguifactory.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DIALOGUIFACTORY_H
-#define DIALOGUIFACTORY_H
-
-#include "abstractuijobs.h"
-#include "abstractuimanager.h"
-
-class KPasswordDialog;
-
-class DialogAskPasswordJob : public AbstractAskPasswordJob
-{
- Q_OBJECT
-
-public:
- /**
- * Constructor.
- */
- DialogAskPasswordJob(AbstractUiManager *manager, const QString& collection, bool \
secondTry);
-
- /**
- * Destructor.
- */
- ~DialogAskPasswordJob();
-
- /**
- * Contains the actual workload of showing the dialog.
- */
- virtual void start();
-
-private Q_SLOTS:
- /**
- * Called when the dialog shown is either accepted or rejected.
- */
- void dialogFinished(int result);
-
-private:
- KPasswordDialog *m_dialog;
-};
-
-/**
- * Implement AbstractUiFactory to provide a user interface using dialogs.
- */
-class DialogUiFactory : public AbstractUiManager
-{
-public:
- /**
- * Destructor.
- */
- virtual ~DialogUiFactory() {};
-
- /**
- * Create a job to ask for a user's password to unlock a collection.
- */
- virtual AbstractAskPasswordJob* createAskPasswordJob(const QString& collection,
- bool secondTry);
-};
-
-#endif
diff --git a/backend/tests/CMakeLists.txt b/backend/tests/CMakeLists.txt
index c9106a5..3951b1d 100644
--- a/backend/tests/CMakeLists.txt
+++ b/backend/tests/CMakeLists.txt
@@ -12,13 +12,4 @@ ADD_TEST (BackendItemCollectionHandlingTest \
ksecretservice_backend_test) KDE4_ADD_EXECUTABLE (securebuffer_test \
securebuffertest.cpp) TARGET_LINK_LIBRARIES (securebuffer_test ksecretservicebackend \
${QT_QTTEST_LIBRARIES})
-# involves dialogs, thus not an automatic test
-KDE4_ADD_EXECUTABLE (dialoguifactory_test dialoguifactorytest.cpp)
-TARGET_LINK_LIBRARIES (dialoguifactory_test
- ksecretservicebackend
- ksecretservicelib
- ${QT_QTTEST_LIBRARIES}
- ${KDE4_KDEUI_LIBS}
-)
-
ADD_TEST (SecureBufferTest securebuffer_test)
diff --git a/backend/tests/dialoguifactorytest.cpp \
b/backend/tests/dialoguifactorytest.cpp deleted file mode 100644
index 73f1a02..0000000
--- a/backend/tests/dialoguifactorytest.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "dialoguifactorytest.h"
-
-#include <QtCrypto/QtCrypto>
-#include <qtest_kde.h>
-
-#include "../dialoguifactory.h"
-
-void DialogUiFactoryTest::initTestCase()
-{
- QCA::init();
-}
-
-void DialogUiFactoryTest::testAskPassword()
-{
- DialogUiFactory fact;
-
- // ask for a password (asynchronously)
- AbstractAskPasswordJob *asyncJob1 = \
fact.createAskPasswordJob("TESTCOLLECTION-ASYNC1", false);
- AbstractAskPasswordJob *asyncJob2 = \
fact.createAskPasswordJob("TESTCOLLECTION-ASYNC2", false);
- QEventLoop loop;
- connect(asyncJob2, SIGNAL(result(QueuedJob*)), &loop, SLOT(quit()));
- asyncJob1->enqueue();
- asyncJob2->enqueue();
- loop.exec();
-}
-
-void DialogUiFactoryTest::cleanupTestCase()
-{
-}
-
-QTEST_KDEMAIN(DialogUiFactoryTest, GUI)
-#include "dialoguifactorytest.moc"
diff --git a/backend/tests/dialoguifactorytest.h \
b/backend/tests/dialoguifactorytest.h deleted file mode 100644
index d862ea7..0000000
--- a/backend/tests/dialoguifactorytest.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DIALOGUIFACTORYTEST_H
-#define DIALOGUIFACTORYTEST_H
-
-#include <QtTest>
-
-class DialogUiFactoryTest : public QObject
-{
- Q_OBJECT
-
-private Q_SLOTS:
- void initTestCase();
-
- void testAskPassword();
-
- void cleanupTestCase();
-};
-
-#endif // BACKENDTEST_H
diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt
deleted file mode 100644
index 13bceb9..0000000
--- a/daemon/CMakeLists.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-INCLUDE_DIRECTORIES (${CMAKE_CURRENT_SOURCE_DIR})
-ADD_SUBDIRECTORY (tests)
-
-SET (ksecretservice_daemon_SRCS
- # Daemon
- item.cpp
- collection.cpp
- prompt.cpp
- secret.cpp
- service.cpp
- session.cpp
-
- # Daemon DBus adaptors
- dbus/dbustypes.cpp
- dbus/collectionadaptor.cpp
- dbus/itemadaptor.cpp
- dbus/promptadaptor.cpp
- dbus/serviceadaptor.cpp
- dbus/sessionadaptor.cpp
-)
-
-KDE4_ADD_LIBRARY (ksecretservicedaemon STATIC ${ksecretservice_daemon_SRCS})
-TARGET_LINK_LIBRARIES (ksecretservicedaemon ${KDE4_KDECORE_LIBS} ${QCA2_LIBRARIES})
diff --git a/daemon/collection.cpp b/daemon/collection.cpp
deleted file mode 100644
index 15d8ce6..0000000
--- a/daemon/collection.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "collection.h"
-#include "dbus/collectionadaptor.h"
-#include "service.h"
-#include "item.h"
-#include "session.h"
-#include "prompt.h"
-
-#include <backend/backendcollection.h>
-#include <backend/backenditem.h>
-
-#include <QtDBus/QDBusConnection>
-
-#include <QtCore/QDebug>
-
-Collection::Collection(BackendCollection *collection, Service *service)
- : QObject(service), m_service(service), m_collection(collection)
-{
- Q_ASSERT(collection);
- m_objectPath.setPath(service->objectPath().path() + "/collection/" + \
collection->id());
-
- new orgFreedesktopSecret::CollectionAdaptor(this);
- QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
-
- connect(collection, SIGNAL(itemCreated(BackendItem*)),
- SLOT(slotItemCreated(BackendItem*)));
- connect(collection, SIGNAL(itemDeleted(BackendItem*)),
- SLOT(slotItemDeleted(BackendItem*)));
- connect(collection, SIGNAL(itemChanged(BackendItem*)),
- SLOT(slotItemChanged(BackendItem*)));
-}
-
-const QDBusObjectPath &Collection::objectPath() const
-{
- return m_objectPath;
-}
-
-const QList<QDBusObjectPath> &Collection::items() const
-{
- return m_items;
-}
-
-void Collection::setLabel(const QString &label)
-{
- BackendReturn<void> rc = m_collection->setLabel(label);
- if (rc.isError()) {
- // TODO: generate D-Bus error
- }
-}
-
-QString Collection::label() const
-{
- BackendReturn<QString> rc = m_collection->label();
- if (rc.isError()) {
- // TODO: generate D-Bus error
- }
- return rc.value();
-}
-
-bool Collection::locked() const
-{
- return m_collection->isLocked();
-}
-
-qulonglong Collection::created() const
-{
- return m_collection->created().toTime_t();
-}
-
-qulonglong Collection::modified() const
-{
- return m_collection->modified().toTime_t();
-}
-
-QDBusObjectPath Collection::deleteCollection()
-{
- DeleteCollectionJob *dcj = m_collection->createDeleteJob();
- if (dcj->isImmediate()) {
- dcj->exec();
- return QDBusObjectPath("/");
- } else {
- SingleJobPrompt *p = new SingleJobPrompt(m_service, dcj, this);
- return p->objectPath();
- }
-}
-
-QList<QDBusObjectPath> Collection::searchItems(const QMap<QString, QString> \
&attributes)
-{
- QList<QDBusObjectPath> rc;
- BackendReturn<QList<BackendItem*> > br = m_collection->searchItems(attributes);
- if (br.isError()) {
- // TODO: generate D-Bus error
- }
- else {
- Q_FOREACH(BackendItem *item, br.value()) {
- rc.append(QDBusObjectPath(m_objectPath.path() + "/" + item->id()));
- }
- }
- return rc;
-}
-
-QDBusObjectPath Collection::createItem(const QMap<QString, QVariant> &properties,
- const Secret &secret, bool replace,
- QDBusObjectPath &prompt)
-{
- // default label?
- QString label;
- QMap<QString, QString> attributes;
- bool locked = false;
-
- // get the session object
- QObject *object = \
QDBusConnection::sessionBus().objectRegisteredAt(secret.session().path());
- Session *session;
- if (!(session = qobject_cast<Session*>(object))) {
- // TODO: error, requires session
- }
-
- if (properties.contains("Label")) {
- label = properties["Label"].toString();
- }
- if (properties.contains("Locked")) {
- locked = properties["Locked"].toBool();
- }
- if (properties.contains("Attributes")) {
- attributes = qdbus_cast<StringStringMap>(properties["Attributes"].value<QDBusArgument>());
- }
-
- // TODO: check the parameters before creating the prompt
- bool ok;
- QCA::SecureArray secretValue = session->decrypt(secret, ok);
- if (!ok) {
- // TODO: invalid session
- }
- CreateItemJob *cij = m_collection->createCreateItemJob(label, attributes, \
secretValue,
- replace, locked);
- if (cij->isImmediate()) {
- cij->exec();
- if (cij->error() != NoError || !cij->item()) {
- // TODO: error creating the item
- }
-
- // the Item is already created inside slotItemCreated()
- prompt.setPath("/");
- QDBusObjectPath itemPath(m_objectPath.path() + "/" + cij->item()->id());
- return itemPath;
- } else {
- SingleJobPrompt *p = new SingleJobPrompt(m_service, cij, this);
- prompt = p->objectPath();
- return QDBusObjectPath("/");
- }
-}
-
-BackendCollection *Collection::backendCollection() const
-{
- return m_collection;
-}
-
-void Collection::slotItemCreated(BackendItem *item)
-{
- Q_ASSERT(item);
- Item *itm = new Item(item, this);
- m_items.append(itm->objectPath());
- emit itemCreated(itm->objectPath());
-}
-
-void Collection::slotItemDeleted(BackendItem *item)
-{
- Q_ASSERT(item);
- QDBusObjectPath itmPath(m_objectPath.path() + "/" + item->id());
- m_items.removeAll(itmPath);
- emit itemDeleted(itmPath);
-}
-
-void Collection::slotItemChanged(BackendItem *item)
-{
- Q_ASSERT(item);
- QDBusObjectPath itmPath(m_objectPath.path() + "/" + item->id());
- emit itemChanged(itmPath);
-}
-
-#include "collection.moc"
diff --git a/daemon/collection.h b/daemon/collection.h
deleted file mode 100644
index f96b414..0000000
--- a/daemon/collection.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAEMON_COLLECTION_H
-#define DAEMON_COLLECTION_H
-
-#include "secret.h"
-
-#include <QtCore/QObject>
-#include <QtDBus/QDBusObjectPath>
-
-class BackendCollection;
-class BackendItem;
-
-class Service;
-class Item;
-
-/**
- * Represents a collection on the D-Bus implementing the \
org.freedesktop.Secret.Collection
- * interface.
- */
-class Collection : public QObject
-{
- Q_OBJECT
-
-public:
- /**
- * Constructor.
- *
- * @param collection Backend collection object
- * @param service Parent service
- */
- Collection(BackendCollection *collection, Service *service);
-
- /**
- * Return the collection's path on the D-Bus.
- *
- * @return the Collection object's path
- */
- const QDBusObjectPath &objectPath() const;
-
- /**
- * Get the items stored inside this collection.
- *
- * @return a list of object paths of items inside the collection
- */
- const QList<QDBusObjectPath> &items() const;
-
- /**
- * Set the collection's label.
- *
- * @param label label to set for the collection
- */
- void setLabel(const QString &label);
-
- /**
- * Get the collection's label.
- *
- * @return the collection's label
- */
- QString label() const;
-
- /**
- * Check whether this collection is locked.
- *
- * @return true if the collection is locked, false if it is unlocked
- */
- bool locked() const;
-
- /**
- * Get the collection's creation time as a unix timestamp.
- *
- * @return collection's creation time
- */
- qulonglong created() const;
-
- /**
- * Get the collection's last modification time as a unix timestamp.
- *
- * @return collection's modification time
- */
- qulonglong modified() const;
-
- /**
- * Delete this collection.
- *
- * @return the object path of a Prompt object or special value "/" if the
- * collection was deleted without prompting
- */
- QDBusObjectPath deleteCollection();
-
- /**
- * Search items inside the collection.
- *
- * @param attributes search attributes to match items against
- */
- QList<QDBusObjectPath> searchItems(const QMap<QString, QString> &attributes);
-
- /**
- * Create a new item inside the collection.
- *
- * @param properties Properties for the new item
- * @param secret Secret for the new item
- * @param replace if true, an existing item with the same attributes will be \
replaced,
- * if false and an item with the same attributes exists, no new \
item
- * will be created
- * @param prompt object path of a prompt object if prompting is necessary or "/" \
if
- * the action could be completed without a prompt
- * @return object path of the new item or "/" if prompting is necessary
- */
- QDBusObjectPath createItem(const QMap<QString, QVariant> &properties,
- const Secret &secret, bool replace, QDBusObjectPath \
&prompt);
-
- /**
- * Get the backend collection linked to this object.
- */
- BackendCollection *backendCollection() const;
-
-Q_SIGNALS:
- /**
- * Signals the creation of a new item.
- *
- * @param item object path of the item that was created
- */
- void itemCreated(const QDBusObjectPath &item);
-
- /**
- * Signals the deletion of an item.
- *
- * @param item object path of the item that was deleted
- */
- void itemDeleted(const QDBusObjectPath &item);
-
- /**
- * Signals that an item inside the collection was changed.
- *
- * @param item object path of the item that was changed
- */
- void itemChanged(const QDBusObjectPath &item);
-
-private Q_SLOTS:
- // handle itemCreated() calls from a backend collection
- void slotItemCreated(BackendItem *item);
- // handle itemDeleted() calls from a backend collection
- void slotItemDeleted(BackendItem *item);
- // handle itemChanged() calls from a backend collection
- void slotItemChanged(BackendItem *item);
-
-private:
- Service *m_service; // parent service
- BackendCollection *m_collection;
- QDBusObjectPath m_objectPath;
- QList<QDBusObjectPath> m_items; // cache for items' object paths
-};
-
-#endif
diff --git a/daemon/dbus/collectionadaptor.cpp b/daemon/dbus/collectionadaptor.cpp
deleted file mode 100644
index 35b431a..0000000
--- a/daemon/dbus/collectionadaptor.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "collectionadaptor.h"
-#include "../collection.h"
-
-namespace orgFreedesktopSecret
-{
-
-CollectionAdaptor::CollectionAdaptor(Collection *collection)
- : QDBusAbstractAdaptor(collection), m_collection(collection)
-{
- Q_ASSERT(collection);
-
- connect(m_collection, SIGNAL(itemCreated(const QDBusObjectPath &)),
- SIGNAL(ItemCreated(const QDBusObjectPath &)));
- connect(m_collection, SIGNAL(itemDeleted(const QDBusObjectPath &)),
- SIGNAL(ItemDeleted(const QDBusObjectPath &)));
- connect(m_collection, SIGNAL(itemChanged(const QDBusObjectPath &)),
- SIGNAL(ItemChanged(const QDBusObjectPath &)));
-}
-
-const QList<QDBusObjectPath> &CollectionAdaptor::items() const
-{
- return m_collection->items();
-}
-
-void CollectionAdaptor::setLabel(const QString &label)
-{
- m_collection->setLabel(label);
-}
-
-QString CollectionAdaptor::label() const
-{
- return m_collection->label();
-}
-
-bool CollectionAdaptor::locked() const
-{
- return m_collection->locked();
-}
-
-qulonglong CollectionAdaptor::created() const
-{
- return m_collection->created();
-}
-
-qulonglong CollectionAdaptor::modified() const
-{
- return m_collection->modified();
-}
-
-QDBusObjectPath CollectionAdaptor::Delete()
-{
- return m_collection->deleteCollection();
-}
-
-QList<QDBusObjectPath> CollectionAdaptor::SearchItems(const StringStringMap \
&attributes)
-{
- return m_collection->searchItems(attributes);
-}
-
-QDBusObjectPath CollectionAdaptor::CreateItem(const QMap<QString, QVariant> \
&properties,
- const Secret &secret, bool replace,
- QDBusObjectPath &prompt)
-{
- return m_collection->createItem(properties, secret, replace, prompt);
-}
-
-}
-
-#include "collectionadaptor.moc"
diff --git a/daemon/dbus/collectionadaptor.h b/daemon/dbus/collectionadaptor.h
deleted file mode 100644
index cb7ad00..0000000
--- a/daemon/dbus/collectionadaptor.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ORG_FREEDESKTOP_SECRET_COLLECTIONADAPTOR_H
-#define ORG_FREEDESKTOP_SECRET_COLLECTIONADAPTOR_H
-
-#include "dbustypes.h"
-
-#include <QtDBus/QDBusAbstractAdaptor>
-
-class Collection;
-
-namespace orgFreedesktopSecret
-{
-
-/**
- * D-Bus adaptor class for Collection objects.
- */
-class CollectionAdaptor : public QDBusAbstractAdaptor
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Collection")
- Q_PROPERTY(QList<QDBusObjectPath> Items READ items)
- Q_PROPERTY(QString Label READ label WRITE setLabel)
- Q_PROPERTY(bool Locked READ locked)
- Q_PROPERTY(qulonglong Created READ created)
- Q_PROPERTY(qulonglong Modified READ modified)
-
-public:
- /**
- * Constructor.
- *
- * @param collection collection object to attach the adaptor to
- */
- CollectionAdaptor(Collection *collection);
-
- const QList<QDBusObjectPath> &items() const;
-
- void setLabel(const QString &label);
-
- QString label() const;
-
- bool locked() const;
-
- qulonglong created() const;
-
- qulonglong modified() const;
-
-public Q_SLOTS:
- QDBusObjectPath Delete();
-
- QList<QDBusObjectPath> SearchItems(const StringStringMap &attributes);
-
- QDBusObjectPath CreateItem(const QMap<QString, QVariant> &properties,
- const Secret &secret, bool replace,
- QDBusObjectPath &prompt);
-
-Q_SIGNALS:
- void ItemCreated(const QDBusObjectPath &item);
-
- void ItemDeleted(const QDBusObjectPath &item);
-
- void ItemChanged(const QDBusObjectPath &item);
-
-private:
- Collection *m_collection;
-};
-
-}
-
-#endif
diff --git a/daemon/dbus/dbustypes.cpp b/daemon/dbus/dbustypes.cpp
deleted file mode 100644
index 6d5362f..0000000
--- a/daemon/dbus/dbustypes.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "dbustypes.h"
-
-#include <QtDBus/QDBusMetaType>
-
-void registerDBusTypes()
-{
- // register meta-types needed for this adaptor
- qRegisterMetaType<Secret>();
- qDBusRegisterMetaType<Secret>();
- qRegisterMetaType<StringStringMap>();
- qDBusRegisterMetaType<StringStringMap>();
- qDBusRegisterMetaType<ObjectPathSecretMap>();
-}
diff --git a/daemon/dbus/dbustypes.h b/daemon/dbus/dbustypes.h
deleted file mode 100644
index 12425dc..0000000
--- a/daemon/dbus/dbustypes.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ORG_FREEDESKTOP_SECRET_DBUSTYPES_H
-#define ORG_FREEDESKTOP_SECRET_DBUSTYPES_H
-
-#include "../secret.h"
-
-#include <QtDBus/QDBusObjectPath>
-#include <QtCore/QMap>
-#include <QtCore/QString>
-
-/**
- * Register the types needed for the fd.o Secrets D-Bus interface.
- */
-void registerDBusTypes();
-
-typedef QMap<QString, QString> StringStringMap;
-typedef QMap<QDBusObjectPath, Secret> ObjectPathSecretMap;
-
-Q_DECLARE_METATYPE(StringStringMap);
-Q_DECLARE_METATYPE(ObjectPathSecretMap);
-
-#endif
diff --git a/daemon/dbus/itemadaptor.cpp b/daemon/dbus/itemadaptor.cpp
deleted file mode 100644
index 04f68ea..0000000
--- a/daemon/dbus/itemadaptor.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "itemadaptor.h"
-#include "../item.h"
-#include "../secret.h"
-
-namespace orgFreedesktopSecret
-{
-
-ItemAdaptor::ItemAdaptor(Item *item)
- : QDBusAbstractAdaptor(item), m_item(item)
-{
- Q_ASSERT(item);
-}
-
-bool ItemAdaptor::locked() const
-{
- return m_item->locked();
-}
-
-void ItemAdaptor::setAttributes(const StringStringMap &attributes)
-{
- m_item->setAttributes(attributes);
-}
-
-StringStringMap ItemAdaptor::attributes() const
-{
- return m_item->attributes();
-}
-
-void ItemAdaptor::setLabel(const QString &label)
-{
- m_item->setLabel(label);
-}
-
-QString ItemAdaptor::label() const
-{
- return m_item->label();
-}
-
-qulonglong ItemAdaptor::created() const
-{
- return m_item->created();
-}
-
-qulonglong ItemAdaptor::modified() const
-{
- return m_item->modified();
-}
-
-QDBusObjectPath ItemAdaptor::Delete()
-{
- return m_item->deleteItem();
-}
-
-Secret ItemAdaptor::GetSecret(const QDBusObjectPath &session)
-{
- return m_item->getSecret(session);
-}
-
-void ItemAdaptor::SetSecret(const Secret &secret)
-{
- m_item->setSecret(secret);
-}
-
-}
-
-#include "itemadaptor.moc"
diff --git a/daemon/dbus/itemadaptor.h b/daemon/dbus/itemadaptor.h
deleted file mode 100644
index 2037c17..0000000
--- a/daemon/dbus/itemadaptor.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ORG_FREEDESKTOP_SECRET_ITEMADAPTOR_H
-#define ORG_FREEDESKTOP_SECRET_ITEMADAPTOR_H
-
-#include "dbustypes.h"
-
-#include <QtDBus/QDBusAbstractAdaptor>
-#include <QtCore/QString>
-#include <QtCore/QMap>
-
-class Item;
-
-namespace orgFreedesktopSecret
-{
-
-/**
- * D-Bus adaptor class for Item objects.
- */
-class ItemAdaptor : public QDBusAbstractAdaptor
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Item")
- Q_PROPERTY(bool Locked READ locked)
- Q_PROPERTY(StringStringMap Attributes READ attributes WRITE setAttributes)
- Q_PROPERTY(QString Label READ label WRITE setLabel)
- Q_PROPERTY(qulonglong Created READ created)
- Q_PROPERTY(qulonglong Modified READ modified)
-
-public:
- /**
- * Constructor.
- *
- * @param item item object to attach the adaptor to
- */
- ItemAdaptor(Item *item);
-
- bool locked() const;
-
- void setAttributes(const StringStringMap &attributes);
-
- StringStringMap attributes() const;
-
- void setLabel(const QString &label);
-
- QString label() const;
-
- qulonglong created() const;
-
- qulonglong modified() const;
-
-public Q_SLOTS:
- QDBusObjectPath Delete();
-
- Secret GetSecret(const QDBusObjectPath &session);
-
- void SetSecret(const Secret &secret);
-
-private:
- Item *m_item;
-};
-
-}
-
-#endif
diff --git a/daemon/dbus/promptadaptor.cpp b/daemon/dbus/promptadaptor.cpp
deleted file mode 100644
index 44ddda3..0000000
--- a/daemon/dbus/promptadaptor.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "promptadaptor.h"
-#include "../prompt.h"
-
-namespace orgFreedesktopSecret
-{
-
-PromptAdaptor::PromptAdaptor(PromptBase *prompt)
- : QDBusAbstractAdaptor(prompt), m_prompt(prompt)
-{
- Q_ASSERT(prompt);
-
- connect(prompt, SIGNAL(completed(bool, QVariant)), SLOT(slotCompleted(bool, \
QVariant)));
-}
-
-void PromptAdaptor::Prompt(const QString &windowId)
-{
- m_prompt->prompt(windowId);
-}
-
-void PromptAdaptor::Dismiss()
-{
- m_prompt->dismiss();
-}
-
-void PromptAdaptor::slotCompleted(bool dismissed, const QVariant &result)
-{
- emit Completed(dismissed, QDBusVariant(result));
-}
-
-}
-
-#include "promptadaptor.moc"
diff --git a/daemon/dbus/promptadaptor.h b/daemon/dbus/promptadaptor.h
deleted file mode 100644
index 8338eca..0000000
--- a/daemon/dbus/promptadaptor.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ORG_FREEDESKTOP_SECRET_PROMPTADAPTOR_H
-#define ORG_FREEDESKTOP_SECRET_PROMPTADAPTOR_H
-
-#include "../prompt.h"
-
-#include <QtDBus/QDBusAbstractAdaptor>
-
-namespace orgFreedesktopSecret
-{
-
-/**
- * D-Bus adaptor class for Prompt objects.
- */
-class PromptAdaptor : public QDBusAbstractAdaptor
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Prompt")
-
-public:
- /**
- * Constructor.
- *
- * @param prompt prompt object to attach the adaptor to
- */
- PromptAdaptor(PromptBase *prompt);
-
-public Q_SLOTS:
- void Prompt(const QString &windowId);
-
- void Dismiss();
-
-Q_SIGNALS:
- void Completed(bool dismissed, QDBusVariant result);
-
-private Q_SLOTS:
- void slotCompleted(bool dismissed, const QVariant &result);
-
-private:
- PromptBase *m_prompt;
-};
-
-}
-
-#endif
diff --git a/daemon/dbus/serviceadaptor.cpp b/daemon/dbus/serviceadaptor.cpp
deleted file mode 100644
index 276ba19..0000000
--- a/daemon/dbus/serviceadaptor.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "serviceadaptor.h"
-#include "dbustypes.h"
-#include "../service.h"
-
-namespace orgFreedesktopSecret
-{
-
-ServiceAdaptor::ServiceAdaptor(Service *service)
- : QDBusAbstractAdaptor(service), m_service(service)
-{
- Q_ASSERT(service);
-
- // register all types needed for the D-Bus interface
- registerDBusTypes();
-
- connect(service, SIGNAL(collectionCreated(const QDBusObjectPath&)),
- SIGNAL(CollectionCreated(const QDBusObjectPath&)));
- connect(service, SIGNAL(collectionDeleted(const QDBusObjectPath&)),
- SIGNAL(CollectionDeleted(const QDBusObjectPath&)));
- connect(service, SIGNAL(collectionChanged(const QDBusObjectPath&)),
- SIGNAL(CollectionChanged(const QDBusObjectPath&)));
-}
-
-const QList<QDBusObjectPath> &ServiceAdaptor::collections() const
-{
- return m_service->collections();
-}
-
-QDBusVariant ServiceAdaptor::OpenSession(const QString &algorithm, const \
QDBusVariant &input,
- QDBusObjectPath &result)
-{
- return QDBusVariant(m_service->openSession(algorithm, input.variant(), result));
-}
-
-QDBusObjectPath ServiceAdaptor::CreateCollection(const QMap<QString, QVariant> \
&properties,
- QDBusObjectPath &prompt)
-{
- return m_service->createCollection(properties, prompt);
-}
-
-QList<QDBusObjectPath> ServiceAdaptor::SearchItems(const StringStringMap \
&attributes,
- QList<QDBusObjectPath> &locked)
-{
- return m_service->searchItems(attributes, locked);
-}
-
-QList<QDBusObjectPath> ServiceAdaptor::Unlock(const QList<QDBusObjectPath> &objects,
- QDBusObjectPath &prompt)
-{
- return m_service->unlock(objects, prompt);
-}
-
-QList<QDBusObjectPath> ServiceAdaptor::Lock(const QList<QDBusObjectPath> &objects,
- QDBusObjectPath &prompt)
-{
- return m_service->lock(objects, prompt);
-}
-
-ObjectPathSecretMap ServiceAdaptor::GetSecrets(const QList<QDBusObjectPath> &items,
- const QDBusObjectPath &session)
-{
- return m_service->getSecrets(items, session);
-}
-
-}
-
-#include "serviceadaptor.moc"
diff --git a/daemon/dbus/serviceadaptor.h b/daemon/dbus/serviceadaptor.h
deleted file mode 100644
index 436a4bd..0000000
--- a/daemon/dbus/serviceadaptor.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ORG_FREEDESKTOP_SECRET_SERVICEADAPTOR_H
-#define ORG_FREEDESKTOP_SECRET_SERVICEADAPTOR_H
-
-#include "dbustypes.h"
-#include "../secret.h"
-
-#include <QtDBus/QDBusAbstractAdaptor>
-#include <QtDBus/QDBusObjectPath>
-
-class Service;
-
-namespace orgFreedesktopSecret
-{
-
-/**
- * D-Bus adaptor class for Service objects.
- */
-class ServiceAdaptor : public QDBusAbstractAdaptor
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Service")
- Q_PROPERTY(QList<QDBusObjectPath> Collections READ collections)
-
-public:
- /**
- * Constructor.
- *
- * @param service service object to attach the adaptor to
- */
- ServiceAdaptor(Service *service);
-
- const QList<QDBusObjectPath> &collections() const;
-
-public Q_SLOTS:
- QDBusVariant OpenSession(const QString &algorithm, const QDBusVariant &input,
- QDBusObjectPath &result);
-
- QDBusObjectPath CreateCollection(const QMap<QString, QVariant> &properties,
- QDBusObjectPath &prompt);
-
- QList<QDBusObjectPath> SearchItems(const StringStringMap &attributes,
- QList<QDBusObjectPath> &locked);
-
- QList<QDBusObjectPath> Unlock(const QList<QDBusObjectPath> &objects, \
QDBusObjectPath &prompt);
-
- QList<QDBusObjectPath> Lock(const QList<QDBusObjectPath> &objects, \
QDBusObjectPath &prompt);
-
- ObjectPathSecretMap GetSecrets(const QList<QDBusObjectPath> &items,
- const QDBusObjectPath &session);
-
-Q_SIGNALS:
- void CollectionCreated(const QDBusObjectPath &collection);
-
- void CollectionDeleted(const QDBusObjectPath &collection);
-
- void CollectionChanged(const QDBusObjectPath &collection);
-
-private:
- Service *m_service;
-};
-
-}
-
-#endif
diff --git a/daemon/dbus/sessionadaptor.cpp b/daemon/dbus/sessionadaptor.cpp
deleted file mode 100644
index e2d1e53..0000000
--- a/daemon/dbus/sessionadaptor.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "sessionadaptor.h"
-#include "../session.h"
-
-namespace orgFreedesktopSecret
-{
-
-SessionAdaptor::SessionAdaptor(Session *session)
- : QDBusAbstractAdaptor(session), m_session(session)
-{
- Q_ASSERT(session);
-}
-
-void SessionAdaptor::Close()
-{
- m_session->close();
-}
-
-}
-
-#include "sessionadaptor.moc"
diff --git a/daemon/dbus/sessionadaptor.h b/daemon/dbus/sessionadaptor.h
deleted file mode 100644
index 0eb553c..0000000
--- a/daemon/dbus/sessionadaptor.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ORG_FREEDESKTOP_SECRET_SESSIONADAPTOR_H
-#define ORG_FREEDESKTOP_SECRET_SESSIONADAPTOR_H
-
-#include <QtDBus/QDBusAbstractAdaptor>
-
-class Session;
-
-namespace orgFreedesktopSecret
-{
-
-/**
- * D-Bus adaptor class for Session objects.
- */
-class SessionAdaptor : public QDBusAbstractAdaptor
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Session")
-
-public:
- /**
- * Constructor.
- *
- * @param session session object to attach the adaptor to
- */
- SessionAdaptor(Session *session);
-
-public Q_SLOTS:
- void Close();
-
-private:
- Session *m_session;
-};
-
-}
-
-#endif
diff --git a/daemon/item.cpp b/daemon/item.cpp
deleted file mode 100644
index 93e1b09..0000000
--- a/daemon/item.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "item.h"
-#include "collection.h"
-#include "dbus/itemadaptor.h"
-#include "session.h"
-#include "secret.h"
-#include "prompt.h"
-
-#include <backend/backenditem.h>
-
-#include <QtDBus/QDBusConnection>
-
-Item::Item(BackendItem *item, Collection *collection)
- : QObject(collection), m_item(item)
-{
- Q_ASSERT(item);
- m_objectPath.setPath(collection->objectPath().path() + "/" + item->id());
-
- new orgFreedesktopSecret::ItemAdaptor(this);
- QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
-}
-
-const QDBusObjectPath &Item::objectPath() const
-{
- return m_objectPath;
-}
-
-bool Item::locked() const
-{
- return m_item->isLocked();
-}
-
-void Item::setAttributes(const QMap<QString, QString> &attributes)
-{
- BackendReturn<void> rc = m_item->setAttributes(attributes);
- if (rc.isError()) {
- // TODO: set D-Bus error
- }
-}
-
-QMap<QString, QString> Item::attributes() const
-{
- BackendReturn<QMap<QString, QString> > rc = m_item->attributes();
- if (rc.isError()) {
- // TODO: set D-Bus error
- }
- return rc.value();
-}
-
-void Item::setLabel(const QString &label)
-{
- BackendReturn<void> rc = m_item->setLabel(label);
- if (rc.isError()) {
- // TODO: set D-Bus error
- }
-}
-
-QString Item::label() const
-{
- BackendReturn<QString> rc = m_item->label();
- if (rc.isError()) {
- // TODO: set D-Bus error
- }
- return rc.value();
-}
-
-qulonglong Item::created() const
-{
- return m_item->created().toTime_t();
-}
-
-qulonglong Item::modified() const
-{
- return m_item->modified().toTime_t();
-}
-
-QDBusObjectPath Item::deleteItem()
-{
- DeleteItemJob *dij = m_item->createDeleteJob();
- if (dij->isImmediate()) {
- dij->exec();
- return QDBusObjectPath("/");
- } else {
- // FIXME: needs the service!
- SingleJobPrompt *p = new SingleJobPrompt(0, dij, this);
- return p->objectPath();
- }
-}
-
-Secret Item::getSecret(const QDBusObjectPath &session)
-{
- if (m_item->isLocked()) {
- // TODO: error, requires unlocking
- return Secret();
- }
-
- QObject *object = \
QDBusConnection::sessionBus().objectRegisteredAt(session.path());
- Session *sessionObj;
- if (object && (sessionObj = qobject_cast<Session*>(object))) {
- BackendReturn<QCA::SecureArray> br = m_item->secret();
- if (br.isError()) {
- // TODO: handle error
- return Secret();
- }
- bool ok;
- Secret secret = sessionObj->encrypt(br.value(), ok);
- if (br.isError()) {
- // TODO: error, invalid session
- return Secret();
- }
- return secret;
- } else {
- // TODO: error, requires session
- return Secret();
- }
-}
-
-void Item::setSecret(const Secret &secret)
-{
- if (m_item->isLocked()) {
- // TODO: error, requires unlocking
- return;
- }
-
- QObject *object = \
QDBusConnection::sessionBus().objectRegisteredAt(secret.session().path());
- Session *sessionObj;
- if (object && (sessionObj = qobject_cast<Session*>(object))) {
- bool ok;
- BackendReturn<QCA::SecureArray> br = sessionObj->decrypt(secret, ok);
- if (!ok) {
- // TODO: invalid session
- return;
- }
- BackendReturn<void> rc = m_item->setSecret(br.value());
- if (rc.isError()) {
- // TODO: handle error
- return;
- }
- }
-
- // TODO: error, invalid session
-
- return;
-}
-
-BackendItem *Item::backendItem() const
-{
- return m_item;
-}
-
-#include "item.moc"
diff --git a/daemon/item.h b/daemon/item.h
deleted file mode 100644
index b53df41..0000000
--- a/daemon/item.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAEMON_ITEM_H
-#define DAEMON_ITEM_H
-
-#include "secret.h"
-
-#include <QtCore/QObject>
-#include <QtDBus/QDBusContext>
-
-class BackendItem;
-class Collection;
-class Service;
-
-/**
- * Represents an item on the D-Bus implementing the org.freedesktop.Secret.Item
- * interface.
- */
-class Item : public QObject, protected QDBusContext
-{
- Q_OBJECT
-
-public:
- /**
- * Constructor.
- *
- * @param item Backend item object
- * @param collection Parent collection
- */
- Item(BackendItem *item, Collection *collection);
-
- /**
- * Return the item's path on the D-Bus.
- *
- * @return the Item object's path
- */
- const QDBusObjectPath &objectPath() const;
-
-public: // called by D-Bus adaptors
-
- /**
- * Check whether this item is locked.
- *
- * @return true if the item is locked, false if it is unlocked
- */
- bool locked() const;
-
- /**
- * Set the item's attributes.
- *
- * @param attributes the attributes to set for the item
- */
- void setAttributes(const QMap<QString, QString> &attributes);
-
- /**
- * Get the item's attributes.
- *
- * @return the attributes stored for this item
- */
- QMap<QString, QString> attributes() const;
-
- /**
- * Set the item's human-readable label.
- *
- * @param label label to assign to this item
- */
- void setLabel(const QString &label);
-
- /**
- * Get the human-readable label assigned to this item.
- *
- * @return the item assigned to this item
- */
- QString label() const;
-
- /**
- * Retrieve the item's time of creation as a unix timestamp.
- *
- * @return item's time of creation
- */
- qulonglong created() const;
-
- /**
- * Retrieve the item's last modification date as a unix timestamp.
- *
- * @return item's last time of modification
- */
- qulonglong modified() const;
-
- /**
- * Delete the item from the collection it's in.
- *
- * @return the object path of a prompt object for the operation or "/" if the
- * item was deleted without a prompt.
- */
- QDBusObjectPath deleteItem();
-
- /**
- * Get the secret stored withing the item.
- *
- * @param session Session to use for securing the D-Bus transport
- * @return the (possibly encrypted) Secret structure
- */
- Secret getSecret(const QDBusObjectPath &session);
-
- /**
- * Set the secret stored within the item.
- *
- * @param secret Secret to store inside the item
- */
- void setSecret(const Secret &secret);
-
-public:
- /**
- * Get the backend item associated with this frontend item.
- *
- * @return the backend item belonging to this frontend item
- * @remarks called by other frontend objects
- */
- BackendItem *backendItem() const;
-
-private:
- BackendItem *m_item;
- QDBusObjectPath m_objectPath;
-};
-
-#endif
diff --git a/daemon/prompt.cpp b/daemon/prompt.cpp
deleted file mode 100644
index ad92607..0000000
--- a/daemon/prompt.cpp
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "prompt.h"
-#include "service.h"
-#include "dbus/promptadaptor.h"
-
-#include <backend/backendcollection.h>
-#include <backend/backenditem.h>
-#include <secrettool.h>
-
-#include <QtDBus/QDBusConnection>
-#include <QtDBus/QDBusObjectPath>
-
-PromptBase::PromptBase(Service *service, QObject *parent)
- : QObject(parent), m_serviceObjectPath(service->objectPath())
-{
- Q_ASSERT(service);
- m_objectPath.setPath(service->objectPath().path() + "/prompts/" + createId());
-
- new orgFreedesktopSecret::PromptAdaptor(this);
- QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
-}
-
-PromptBase::~PromptBase()
-{
-}
-
-const QDBusObjectPath &PromptBase::objectPath() const
-{
- return m_objectPath;
-}
-
-const QDBusObjectPath &PromptBase::serviceObjectPath() const
-{
- return m_serviceObjectPath;
-}
-
-void PromptBase::emitCompleted(bool dismissed, const QVariant &result)
-{
- emit completed(dismissed, result);
-}
-
-SingleJobPrompt::SingleJobPrompt(Service* service, BackendJob* job, QObject* parent)
- : PromptBase(service, parent), m_prompted(false), m_job(job)
-{
- connect(job, SIGNAL(result(QueuedJob*)), SLOT(jobResult(QueuedJob*)));
-}
-
-SingleJobPrompt::~SingleJobPrompt()
-{
- // TODO: delete the job?
-}
-
-void SingleJobPrompt::prompt(const QString &windowId)
-{
- Q_UNUSED(windowId);
- if (m_prompted) {
- return;
- }
- m_prompted = true;
-
- // TODO: convert windowId to a WId and pass it to the job
- m_job->enqueue();
-}
-
-void SingleJobPrompt::dismiss()
-{
- if (m_prompted) {
- return;
- }
- m_prompted = true;
-
- m_job->dismiss();
-}
-
-void SingleJobPrompt::jobResult(QueuedJob *job)
-{
- Q_ASSERT(job == m_job);
- // check for errors first
- if (m_job->isDismissed()) {
- emit completed(true, QVariant(""));
- } else if (m_job->error() != NoError) {
- // TODO: figure out how to handle errors gracefully.
- emit completed(false, QVariant(""));
- } else {
- switch (m_job->type()) {
-
- case BackendJob::TypeUnlockCollection:
- case BackendJob::TypeLockCollection:
- case BackendJob::TypeDeleteCollection:
- case BackendJob::TypeChangeAuthenticationCollection:
- case BackendJob::TypeDeleteItem:
- case BackendJob::TypeLockItem:
- case BackendJob::TypeUnlockItem:
- case BackendJob::TypeChangeAuthenticationItem:
- {
- BooleanResultJob *brj = qobject_cast<BooleanResultJob*>(m_job);
- Q_ASSERT(brj);
- emitCompleted(false, QVariant(brj->result()));
- }
- break;
-
- case BackendJob::TypeCreateCollectionMaster:
- {
- CreateCollectionMasterJob *ccmj = \
qobject_cast<CreateCollectionMasterJob*>(m_job);
- Q_ASSERT(ccmj);
- QDBusObjectPath result("/");
- if (ccmj->collection()) {
- BackendCollection *coll = ccmj->collection();
- result.setPath(serviceObjectPath().path() + "/collection/" + \
coll->id());
- }
-
- emitCompleted(false, qVariantFromValue(result));
- }
- break;
-
- case BackendJob::TypeCreateCollection:
- {
- CreateCollectionJob *ccj = qobject_cast<CreateCollectionJob*>(m_job);
- Q_ASSERT(ccj);
- QDBusObjectPath result("/");
- if (ccj->collection()) {
- BackendCollection *coll = ccj->collection();
- result.setPath(serviceObjectPath().path() + "/collection/" + \
coll->id());
- }
-
- emitCompleted(false, qVariantFromValue(result));
- }
- break;
-
- case BackendJob::TypeCreateItem:
- {
- CreateItemJob *cij = qobject_cast<CreateItemJob*>(m_job);
- Q_ASSERT(cij);
- QDBusObjectPath result("/");
- if (cij->item()) {
- BackendItem *item = cij->item();
- result.setPath(serviceObjectPath().path() + "/collection/" +
- cij->collection()->id() + "/" + item->id());
- }
-
- emitCompleted(false, qVariantFromValue(result));
- }
- break;
-
- default:
- // should not happen!
- Q_ASSERT(false);
- }
- }
-
- deleteLater();
-}
-
-ServiceMultiPrompt::ServiceMultiPrompt(Service *service, const QSet<BackendJob*> \
jobs,
- QObject *parent)
- : PromptBase(service, parent), m_prompted(false), m_jobs(jobs)
-{
- bool jobTypeDetermined = false;
- bool jobTypeUnlock = false;
-
- Q_FOREACH(BackendJob *job, m_jobs) {
- // make sure the subjobs are either all unlock or all lock calls
- bool currentJobTypeUnlock = (job->type() == BackendJob::TypeUnlockCollection \
||
- job->type() == BackendJob::TypeUnlockItem);
- if (jobTypeDetermined && jobTypeUnlock != currentJobTypeUnlock) {
- Q_ASSERT(false);
- } else if (!jobTypeDetermined) {
- jobTypeUnlock = currentJobTypeUnlock;
- jobTypeDetermined = true;
- }
- connect(job, SIGNAL(result(QueuedJob*)), SLOT(jobResult(QueuedJob*)));
- }
-}
-
-ServiceMultiPrompt::~ServiceMultiPrompt()
-{
- // TODO: delete jobs if not started?
-}
-
-void ServiceMultiPrompt::prompt(const QString &windowId)
-{
- Q_UNUSED(windowId);
- if (m_prompted) {
- return;
- }
- m_prompted = true;
-
- // TODO: convert windowId to a WId and pass it to the job
- Q_FOREACH(BackendJob *job, m_jobs) {
- job->enqueue();
- }
-}
-
-void ServiceMultiPrompt::dismiss()
-{
- if (m_prompted) {
- return;
- }
- m_prompted = true;
-
- Q_FOREACH(BackendJob *job, m_jobs) {
- disconnect(job, SIGNAL(result(QueuedJob*)), this, \
SLOT(jobResult(QueuedJob*)));
- job->dismiss();
- }
-
- // emit result right away so we don't have to catch all result() signals
- // from individual jobs.
- emitCompleted(true, qVariantFromValue(QList<QDBusObjectPath>()));
- deleteLater();
-}
-
-void ServiceMultiPrompt::jobResult(QueuedJob *job)
-{
- BackendJob *bj = qobject_cast<BackendJob*>(job);
- Q_ASSERT(bj);
- Q_ASSERT(m_jobs.contains(bj));
- // remove job from the set of jobs we're waiting for
- m_jobs.remove(bj);
- if (bj->error() != NoError) {
- // TODO: figure out what to do with erroneous jobs
- } else {
- switch (bj->type()) {
-
- case BackendJob::TypeUnlockCollection:
- {
- UnlockCollectionJob *ucj = qobject_cast<UnlockCollectionJob*>(bj);
- Q_ASSERT(ucj);
- if (ucj->result()) {
- BackendCollection *coll = ucj->collection();
- QDBusObjectPath path;
- path.setPath(serviceObjectPath().path() + "/collection/" + \
coll->id());
- m_result.append(path);
- }
- }
- break;
-
- case BackendJob::TypeLockCollection:
- {
- LockCollectionJob *lcj = qobject_cast<LockCollectionJob*>(bj);
- Q_ASSERT(lcj);
- if (lcj->result()) {
- BackendCollection *coll = lcj->collection();
- QDBusObjectPath path;
- path.setPath(serviceObjectPath().path() + "/collection/" + \
coll->id());
- m_result.append(path);
- }
- }
- break;
-
- case BackendJob::TypeUnlockItem:
- {
- UnlockItemJob *uij = qobject_cast<UnlockItemJob*>(bj);
- Q_ASSERT(uij);
- if (uij->result()) {
- BackendItem *item = uij->item();
- BackendCollection *coll = 0;
- // TODO: I NEED THE COLLECTION DAMMIT
- QDBusObjectPath path;
- path.setPath(serviceObjectPath().path() + "/collection/" + coll->id() \
+
- "/" + item->id());
- m_result.append(path);
- }
- }
- break;
-
- case BackendJob::TypeLockItem:
- {
- LockItemJob *lij = qobject_cast<LockItemJob*>(bj);
- Q_ASSERT(lij);
- if (lij->result()) {
- BackendItem *item = lij->item();
- BackendCollection *coll = 0;
- // TODO: I NEED THE COLLECTION DAMMIT
- QDBusObjectPath path;
- path.setPath(serviceObjectPath().path() + "/collection/" + coll->id() \
+
- "/" + item->id());
- m_result.append(path);
- }
- }
- break;
-
- default:
- Q_ASSERT(false);
- }
- }
-
- if (m_jobs.isEmpty()) {
- // all jobs finished
- emitCompleted(false, qVariantFromValue(m_result));
- deleteLater();
- }
-}
-
-#include "prompt.moc"
diff --git a/daemon/prompt.h b/daemon/prompt.h
deleted file mode 100644
index b5aac66..0000000
--- a/daemon/prompt.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAEMON_PROMPT_H
-#define DAEMON_PROMPT_H
-
-#include <backend/backendjob.h>
-
-#include <QtCore/QObject>
-#include <QtCore/QSet>
-#include <QtDBus/QDBusObjectPath>
-#include <QtDBus/QDBusContext>
-
-class Service;
-
-/**
- * Implementation of prompt objects according to the org.freedesktop.Secret.Prompt
- * interface.
- */
-class PromptBase : public QObject, protected QDBusContext
-{
- Q_OBJECT
-
-public:
- /**
- * Constructor.
- *
- * @param service Service object (used to derive the object path of the prompt)
- * @param job the job encapsulated by the prompt
- * @param parent Parent object
- */
- PromptBase(Service *service, QObject *parent);
-
- /**
- * Destructor.
- */
- virtual ~PromptBase();
-
- /**
- * Return the prompt's path on the D-Bus.
- *
- * @return the Prompt object's path
- */
- const QDBusObjectPath &objectPath() const;
-
- /**
- * Return the service object's path on the D-Bus.
- *
- * @return the Service object's path
- */
- const QDBusObjectPath &serviceObjectPath() const;
-
- /**
- * Perform the prompt.
- *
- * @param windowId Platform specific window handle to use for showing the prompt
- * @todo implement window handle handling
- */
- virtual void prompt(const QString &windowId) = 0;
-
- /**
- * Dismiss the prompt.
- */
- virtual void dismiss() = 0;
-
-Q_SIGNALS:
- /**
- * Emitted when the operation performed by the prompt was completed
- *
- * @param dismissed if true the prompt was dismissed, if false it was completed
- * @param result result of the operation encapulated by the prompt object
- */
- void completed(bool dismissed, QVariant result);
-
-protected:
- /**
- * Used to emit completed() signals in derived classes.
- *
- * @param dismissed if true the prompt was dismissed, if false it was completed
- * @param result result of the operation encapsulated by the prompt object
- */
- void emitCompleted(bool dismissed, const QVariant &result);
-
-private:
- QDBusObjectPath m_objectPath; // the prompt object's objectpath
- QDBusObjectPath m_serviceObjectPath; // the service's objectpath
-};
-
-/**
- * Prompt object encapsulating a single BackendJob.
- */
-class SingleJobPrompt : public PromptBase
-{
- Q_OBJECT
-
-public:
- /**
- * Constructor.
- *
- * @param service Service object (used to derive the object path of the prompt)
- * @param job the job encapsulated by the prompt
- * @param parent Parent object
- */
- SingleJobPrompt(Service *service, BackendJob *job, QObject *parent = 0);
-
- /**
- * Destructor.
- */
- virtual ~SingleJobPrompt();
-
- /**
- * Perform the prompt.
- *
- * @param windowId Platform specific window handle to use for showing the prompt
- * @todo implement window handle handling
- */
- virtual void prompt(const QString &windowId);
-
- /**
- * Dismiss the prompt.
- */
- virtual void dismiss();
-
-private Q_SLOTS:
- /**
- * Connected to the backend job's result() signal this notifies about
- * the job's completion.
- *
- * @param job the job that finished
- */
- void jobResult(QueuedJob *job);
-
-private:
- bool m_prompted; // true if one of the prompt()/dismiss() methods has been called \
already
- BackendJob *m_job; // the encapulated job
-};
-
-/**
- * Prompt object encapsulating a Service.Unlock or a Service.Lock call with multiple \
targets.
- */
-class ServiceMultiPrompt : public PromptBase
-{
- Q_OBJECT
-
-public:
- /**
- * Constructor.
- *
- * @param service Service object (used to derive the object path of the prompt)
- * @param jobs the unlock jobs to encapsulate
- * @param parent parent object
- */
- ServiceMultiPrompt(Service *service, const QSet<BackendJob*> jobs, QObject \
*parent = 0);
-
- /**
- * Destructor.
- */
- virtual ~ServiceMultiPrompt();
-
- /**
- * Perform the prompt.
- *
- * @pararm windowId Platform specific window handle to use for showing the prompt
- * @todo implement window handling
- */
- virtual void prompt(const QString &windowId);
-
- /**
- * Dismiss this prompt.
- */
- virtual void dismiss();
-
-private Q_SLOTS:
- /**
- * Connected to the backend jobs' result() signals this notifies about a
- * job's completion.
- *
- * @param job the job that finished
- */
- void jobResult(QueuedJob *job);
-
-private:
- bool m_prompted; // true if one of the prompt()/dismiss() methods has been called \
already
- QList<QDBusObjectPath> m_result; // resulting unlocked/locked object paths
- QSet<BackendJob*> m_jobs; // encapsulated jobs
-};
-
-#endif
diff --git a/daemon/secret.cpp b/daemon/secret.cpp
deleted file mode 100644
index 6639f90..0000000
--- a/daemon/secret.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "secret.h"
-
-#include <QtCore/QSharedData>
-
-Secret::Secret() : d(new SecretData)
-{
-}
-
-Secret::Secret(const Secret &other) : d(other.d)
-{
-}
-
-Secret::~Secret()
-{
-}
-
-void Secret::setSession(const QDBusObjectPath &session)
-{
- d->m_session = session;
-}
-
-const QDBusObjectPath &Secret::session() const
-{
- return d->m_session;
-}
-
-void Secret::setParameters(const QByteArray ¶meters)
-{
- d->m_parameters = parameters;
-}
-
-const QByteArray &Secret::parameters() const
-{
- return d->m_parameters;
-}
-
-void Secret::setValue(const QByteArray &value)
-{
- // TODO: encryption
- d->m_value = value;
-}
-
-const QByteArray &Secret::value() const
-{
- // TODO: decryption
- return d->m_value;
-}
-
-QDBusArgument &operator<<(QDBusArgument &argument, const Secret &secret)
-{
- argument.beginStructure();
- argument << secret.session() << secret.parameters() << secret.value();
- argument.endStructure();
- return argument;
-}
-
-const QDBusArgument &operator>>(const QDBusArgument &argument, Secret &secret)
-{
- QDBusObjectPath session;
- QByteArray parameters;
- QByteArray value;
-
- argument.beginStructure();
- argument >> session >> parameters >> value;
- argument.endStructure();
-
- secret.setSession(session);
- secret.setParameters(parameters);
- secret.setValue(value);
-
- return argument;
-}
diff --git a/daemon/secret.h b/daemon/secret.h
deleted file mode 100644
index 8173faf..0000000
--- a/daemon/secret.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAEMON_SECRET_H
-#define DAEMON_SECRET_H
-
-#include <QtCore/QSharedDataPointer>
-#include <QtCore/QByteArray>
-#include <QtDBus/QDBusObjectPath>
-#include <QtDBus/QDBusArgument>
-#include <QtCrypto/QtCrypto>
-
-/**
- * This class represents secret (possibly encrypted) for transfer on the
- * D-Bus. Encryption and decryption is handled by the respective session.
- *
- * @remarks Objects of this class are implicitly shared
- */
-class Secret
-{
- // TODO: this should actually be inside secret.cpp but I'm getting strange
- // errors if I put it there. investigate.
- class SecretData : public QSharedData
- {
- public:
- SecretData() {}
- SecretData(const SecretData &other)
- : QSharedData(other), m_session(other.m_session), \
m_parameters(other.m_parameters),
- m_value(other.m_value) {}
- ~SecretData() {}
- QDBusObjectPath m_session;
- QByteArray m_parameters;
- QByteArray m_value;
- };
-
-public:
- /**
- * Constructs an empty Secret.
- */
- Secret();
-
- /**
- * Copy constructor.
- */
- Secret(const Secret &other);
-
- /**
- * Destructor.
- */
- ~Secret();
-
- /**
- * Set the session object D-Bus path.
- */
- void setSession(const QDBusObjectPath &session);
-
- /**
- * Get the session object D-Bus path.
- */
- const QDBusObjectPath &session() const;
-
- /**
- * Set the encryption parameters.
- */
- void setParameters(const QByteArray ¶meters);
-
- /**
- * Get the encryption parameters.
- */
- const QByteArray ¶meters() const;
-
- /**
- * Set the secret's encrypted value
- */
- void setValue(const QByteArray &value);
-
- /**
- * Get the secret's encrypted value
- */
- const QByteArray &value() const;
-
-private:
- class SecretData;
- QSharedDataPointer<SecretData> d;
-};
-
-Q_DECLARE_METATYPE(Secret)
-
-QDBusArgument &operator<<(QDBusArgument &argument, const Secret &secret);
-const QDBusArgument &operator>>(const QDBusArgument &argument, Secret &secret);
-
-#endif
diff --git a/daemon/service.cpp b/daemon/service.cpp
deleted file mode 100644
index 280435d..0000000
--- a/daemon/service.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "service.h"
-#include "dbus/serviceadaptor.h"
-#include "collection.h"
-#include "prompt.h"
-#include "session.h"
-#include "secret.h"
-#include "item.h"
-
-#include <backend/backendcollection.h>
-#include <backend/backenditem.h>
-
-#include <QtDBus/QDBusConnection>
-#include <QtDBus/QDBusMetaType>
-#include <QtDBus/QDBusMessage>
-
-Service::Service(BackendMaster *master, QObject *parent)
- : QObject(parent), m_master(master), m_basePath("/org/freedesktop/secrets")
-{
- Q_ASSERT(master);
-
- new orgFreedesktopSecret::ServiceAdaptor(this);
- QDBusConnection::sessionBus().registerObject(m_basePath.path(), this);
-
- // TODO: make master singleton so we can get a KWallet-compatible interface
- // on top of it as well.
-
- connect(m_master, SIGNAL(collectionCreated(BackendCollection*)),
- SLOT(slotCollectionCreated(BackendCollection*)));
- connect(m_master, SIGNAL(collectionDeleted(BackendCollection*)),
- SLOT(slotCollectionDeleted(BackendCollection*)));
- connect(m_master, SIGNAL(collectionChanged(BackendCollection*)),
- SLOT(slotCollectionChanged(BackendCollection*)));
-
- // TODO: add managers to master
-}
-
-const QDBusObjectPath &Service::objectPath() const
-{
- return m_basePath;
-}
-
-const QList<QDBusObjectPath> &Service::collections() const
-{
- return m_collections;
-}
-
-QVariant Service::openSession(const QString &algorithm, const QVariant &input,
- QDBusObjectPath &result)
-{
- QVariant output;
- QString peer;
- if (calledFromDBus()) {
- peer = message().service();
- }
- Session *session = Session::create(algorithm, input, output, peer, this);
- if (session) {
- result = session->objectPath();
- } else {
- result = QDBusObjectPath("/");
- if (calledFromDBus()) {
- sendErrorReply("org.freedesktop.Secret.Error.NotSupported");
- }
- }
- return output;
-}
-
-QDBusObjectPath Service::createCollection(const QMap<QString, QVariant> &properties,
- QDBusObjectPath &prompt)
-{
- // TODO: default label
- QString label;
- bool locked = false;
-
- if (properties.contains("Label")) {
- label = properties["Label"].toString();
- }
- if (properties.contains("Locked")) {
- locked = properties["Locked"].toBool();
- }
-
- CreateCollectionMasterJob *job = m_master->createCreateCollectionMasterJob(label, \
locked);
- if (job->isImmediate()) {
- job->exec();
- if (job->error() != NoError || !job->collection()) {
- // TODO: error creating the collection
- return QDBusObjectPath("/");
- } else {
- BackendCollection *coll = job->collection();
- prompt.setPath("/");
- QDBusObjectPath collPath(m_basePath.path() + "/collection/" + coll->id());
- return collPath;
- }
- } else {
- PromptBase *p = new SingleJobPrompt(this, job, this);
- prompt = p->objectPath();
- return QDBusObjectPath("/");
- }
-}
-
-QList<QDBusObjectPath> Service::searchItems(const QMap<QString, QString> \
&attributes,
- QList<QDBusObjectPath> &locked)
-{
- // TODO: check if session exists
- // TODO: should this rather be implemented using Daemon::Collection?
- QList<QDBusObjectPath> unlocked;
- Q_FOREACH(BackendCollection* collection, m_master->collections()) {
- QString collPath = m_basePath.path() + "/collection/" + collection->id();
- BackendReturn<QList<BackendItem*> > rc = collection->searchItems(attributes);
- if (!rc.isError()) {
- QList<BackendItem*> items = rc.value();
- Q_FOREACH(BackendItem *item, items) {
- if (item->isLocked()) {
- locked.append(QDBusObjectPath(collPath + "/" + item->id()));
- } else {
- unlocked.append(QDBusObjectPath(collPath + "/" + item->id()));
- }
- }
- }
- }
- return unlocked;
-}
-
-QList<QDBusObjectPath> Service::unlock(const QList<QDBusObjectPath> &objects,
- QDBusObjectPath &prompt)
-{
- // TODO: check is session exists
- // TODO: bypass prompt
-
- // objects already unlocked
- QList<QDBusObjectPath> rc;
- // jobs to call asynchronously
- QSet<BackendJob*> unlockJobs;
- QObject *object;
- Item *item;
- Collection *collection;
- BackendItem *bi;
- BackendCollection *bc;
-
- Q_FOREACH(const QDBusObjectPath &path, objects) {
- object = QDBusConnection::sessionBus().objectRegisteredAt(path.path());
- if (!object) {
- continue;
- }
- if ((collection = qobject_cast<Collection*>(object))) {
- bc = collection->backendCollection();
- if (bc) {
- if (!bc->isLocked()) {
- rc.append(path);
- } else {
- UnlockCollectionJob *ucj = bc->createUnlockJob();
- if (ucj->isImmediate()) {
- ucj->exec();
- if (ucj->error() != NoError || !ucj->result()) {
- // not unlocked, maybe due to an error.
- // There's not much to do about it. Silently ignore.
- } else {
- rc.append(path);
- }
- } else {
- unlockJobs.insert(ucj);
- }
- }
- }
- } else if ((item = qobject_cast<Item*>(object))) {
- bi = item->backendItem();
- if (bi) {
- if (!bi->isLocked()) {
- rc.append(path);
- } else {
- UnlockItemJob *uij = bi->createUnlockJob();
- if (uij->isImmediate()) {
- uij->exec();
- if (uij->error() != NoError ||!uij->result()) {
- // not unlocked, maybe due to an error.
- // There's not much to do about it. Silently ignore.
- } else {
- rc.append(path);
- }
- } else {
- unlockJobs.insert(uij);
- }
- }
- }
- }
- // NOTE: objects which either don't exist or whose type is wrong are silently \
ignored.
- }
-
- if (!unlockJobs.isEmpty()) {
- ServiceMultiPrompt *p = new ServiceMultiPrompt(this, unlockJobs, this);
- prompt = p->objectPath();
- } else {
- prompt.setPath("/");
- }
-
- return rc;
-}
-
-QList<QDBusObjectPath> Service::lock(const QList<QDBusObjectPath> &objects,
- QDBusObjectPath &prompt)
-{
- // TODO: check is session exists
-
- // objects already locked
- QList<QDBusObjectPath> rc;
- // jobs to call asynchronously
- QSet<BackendJob*> lockJobs;
- QObject *object;
- Item *item;
- Collection *collection;
- BackendItem *bi;
- BackendCollection *bc;
-
- Q_FOREACH(const QDBusObjectPath &path, objects) {
- object = QDBusConnection::sessionBus().objectRegisteredAt(path.path());
- if (!object) {
- continue;
- }
- if ((collection = qobject_cast<Collection*>(object))) {
- bc = collection->backendCollection();
- if (bc) {
- if (bc->isLocked()) {
- rc.append(path);
- } else {
- LockCollectionJob *lcj = bc->createLockJob();
- if (lcj->isImmediate()) {
- lcj->exec();
- if (lcj->error() != NoError || !lcj->result()) {
- // not locked, maybe due to an error.
- // There's not much to do about it. Silently ignore.
- } else {
- rc.append(path);
- }
- } else {
- lockJobs.insert(lcj);
- }
- }
- }
- } else if ((item = qobject_cast<Item*>(object))) {
- bi = item->backendItem();
- if (bi) {
- if (bi->isLocked()) {
- rc.append(path);
- } else {
- LockItemJob *lij = bi->createLockJob();
- if (lij->isImmediate()) {
- lij->exec();
- if (lij->error() != NoError || !lij->result()) {
- // not locked, maybe due to an error.
- // There's not much to do about it. Silently ignore.
- } else {
- rc.append(path);
- }
- } else {
- lockJobs.insert(lij);
- }
- }
- }
- }
- // NOTE: objects which either don't exist or whose type is wrong are silently \
ignored.
- }
-
- if (!lockJobs.isEmpty()) {
- ServiceMultiPrompt *p = new ServiceMultiPrompt(this, lockJobs, this);
- prompt = p->objectPath();
- } else {
- prompt.setPath("/");
- }
-
- return rc;
-}
-
-QMap<QDBusObjectPath, Secret> Service::getSecrets(const QList<QDBusObjectPath> \
&items,
- const QDBusObjectPath &session)
-{
- QMap<QDBusObjectPath, Secret> rc;
- QObject *object;
- Session *sessionObj;
- Item *item;
- bool ok;
- Secret secret;
-
- object = QDBusConnection::sessionBus().objectRegisteredAt(session.path());
- if (!object || !(sessionObj = qobject_cast<Session*>(object))) {
- if (calledFromDBus()) {
- sendErrorReply("org.freedesktop.Secret.Error.NoSession");
- }
- return rc;
- }
-
- Q_FOREACH(const QDBusObjectPath &path, items) {
- object = QDBusConnection::sessionBus().objectRegisteredAt(path.path());
- if (object && (item = qobject_cast<Item*>(object))) {
- BackendItem *bi = item->backendItem();
- if (bi && !bi->isLocked()) {
- BackendReturn<QCA::SecureArray> be = bi->secret();
- // TODO: what should this do if getting the secret failed?
- if (!be.isError()) {
- secret = sessionObj->encrypt(be.value(), ok);
- // TODO: what should this do if encrypting failed?
- if (ok) {
- rc.insert(path, secret);
- }
- }
- }
- }
- }
-
- return rc;
-}
-
-void Service::slotCollectionCreated(BackendCollection *collection)
-{
- Q_ASSERT(collection);
- Collection *coll = new Collection(collection, this);
- m_collections.append(coll->objectPath());
- emit collectionCreated(coll->objectPath());
-}
-
-void Service::slotCollectionDeleted(BackendCollection *collection)
-{
- Q_ASSERT(collection);
- QDBusObjectPath collPath(m_basePath.path() + "/collection/" + collection->id());
- m_collections.removeAll(collPath);
- // TODO: make sure Daemon::Collection gets destroyed
- emit collectionDeleted(collPath);
-}
-
-void Service::slotCollectionChanged(BackendCollection *collection)
-{
- Q_ASSERT(collection);
- QDBusObjectPath collPath(m_basePath.path() + "/collection/" + collection->id());
- emit collectionChanged(collPath);
-}
-
-#include "service.moc"
diff --git a/daemon/service.h b/daemon/service.h
deleted file mode 100644
index 29a8a98..0000000
--- a/daemon/service.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAEMON_SERVICE_H
-#define DAEMON_SERVICE_H
-
-#include <backend/backendmaster.h>
-
-#include <QtCore/QObject>
-#include <QtCore/QMultiMap>
-#include <QtDBus/QDBusObjectPath>
-#include <QtDBus/QDBusContext>
-
-class Secret;
-class Collection;
-
-class _TypeRegistrar;
-
-/**
- * Main entry point of the secret service D-Bus daemon implementing the
- * org.freedesktop.Secret.Service interface.
- *
- * @todo Implement proper session handling
- */
-class Service : public QObject, protected QDBusContext
-{
- Q_OBJECT
-
-public:
- /**
- * Constructor.
- *
- * @param master Backend master to use
- * @param parent Parent object
- */
- Service(BackendMaster *master, QObject *parent = 0);
-
- /**
- * Return the service's path on the D-Bus.
- *
- * @return the Service object's path
- */
- const QDBusObjectPath &objectPath() const;
-
- /**
- * Accessor for the list of known collections.
- *
- * @return all collections known to the service.
- */
- const QList<QDBusObjectPath> &collections() const;
-
- /**
- * Open a unique session for the caller application.
- *
- * @param algorithm the algorithm the caller wishes to use
- * @param input input arguments for the algorithm
- * @param result the object path of the session, if session was created
- * @return output of the session algorithm negotiation
- */
- QVariant openSession(const QString &algorithm, const QVariant &input, \
QDBusObjectPath &result);
-
- /**
- * Create a new collection with the specified properties.
- *
- * @param properties properties for the new collection
- * @param prompt a prompt object if prompting is necessary, or "/" if no prompt \
was needed
- * @return the new collection object or "/" if prompting is necessary
- */
- QDBusObjectPath createCollection(const QMap<QString, QVariant> &properties,
- QDBusObjectPath &prompt);
-
- /**
- * Find items in any collection.
- *
- * @param attributes the attributes an item has to match in order to be found
- * @param locked items found that require authentication
- * @return items found that are already unlocked
- */
- QList<QDBusObjectPath> searchItems(const QMap<QString, QString> &attributes,
- QList<QDBusObjectPath> &locked);
-
- /**
- * Unlock the specified items or collections.
- *
- * @param objects objects to unlock
- * @param prompt a prompt object which can be used to unlock the remaining \
objects or
- * "/" if no prompt is necessary.
- * @return objects that were unlocked without a prompt
- */
- QList<QDBusObjectPath> unlock(const QList<QDBusObjectPath> &objects, \
QDBusObjectPath &prompt);
-
- /**
- * Lock the specified items or collections.
- *
- * @param objects objects to lock
- * @param prompt a prompt to lock the objects or "/" if no prompt is necessary
- * @return objects that were locked without a prompt
- */
- QList<QDBusObjectPath> lock(const QList<QDBusObjectPath> &objects, \
QDBusObjectPath &prompt);
-
- /**
- * Retrieve multiple secrets from different items.
- *
- * @param items items to get secrets for
- * @param session the session to use to encode the secrets
- * @return the secrets for the items.
- */
- QMap<QDBusObjectPath, Secret> getSecrets(const QList<QDBusObjectPath> &items,
- const QDBusObjectPath &session);
-
-Q_SIGNALS:
- /**
- * Emitted when a new collection is discovered or created.
- *
- * @param collection Objectpath of the collection that was discovered/created
- */
- void collectionCreated(const QDBusObjectPath &collection);
-
- /**
- * Emitted when an existing collection was deleted or disappeared.
- *
- * @param collection Objectpath of the collection that was deleted
- */
- void collectionDeleted(const QDBusObjectPath &collection);
-
- /**
- * Emitted when an existing collection changed.
- *
- * @param collection Objectpath of the collection that changed
- */
- void collectionChanged(const QDBusObjectPath &collection);
-
-private Q_SLOTS:
- // handle collectionCreated() calls from master
- void slotCollectionCreated(BackendCollection *collection);
- // handle collectionDeleted() calls from master
- void slotCollectionDeleted(BackendCollection *collection);
- // handle collectionChanged() calls from master
- void slotCollectionChanged(BackendCollection *collection);
-
-private:
- BackendMaster *m_master;
- QList<QDBusObjectPath> m_collections; // cache object paths of collections
- const QDBusObjectPath m_basePath;
-};
-
-#endif
diff --git a/daemon/session.cpp b/daemon/session.cpp
deleted file mode 100644
index 72a6b16..0000000
--- a/daemon/session.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "session.h"
-#include "dbus/sessionadaptor.h"
-#include "service.h"
-
-#include <secrettool.h>
-
-#include <QtDBus/QDBusConnection>
-#include <QtCore/QRegExp>
-
-#include <QtCore/QDebug>
-
-Session::Session(Service *parent)
- : QObject(parent),
- m_objectPath(parent->objectPath().path() + "/session/" + createId()),
- m_cipher(0)
-{
- // register on the bus
- new orgFreedesktopSecret::SessionAdaptor(this);
- QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
-}
-
-Session::~Session()
-{
- delete m_cipher;
-}
-
-const QDBusObjectPath &Session::objectPath() const
-{
- return m_objectPath;
-}
-
-Session *Session::create(const QString &algorithm, const QVariant &input,
- QVariant &output, const QString &peer, Service *parent)
-{
- static QRegExp rxAlgorithm("^dh-ietf(\\d+)-([^-]+)-([^-]+)-([^-]+)$",
- Qt::CaseInsensitive);
-
- Session *session = 0;
-
- if (algorithm == "plain") {
- session = new Session(parent);
- session->m_encrypted = false;
- output.setValue(QString(""));
- } else if (rxAlgorithm.exactMatch(algorithm) &&
- input.type() == QVariant::ByteArray) {
- QString encalgo = rxAlgorithm.cap(2).toLower();
- QString blockmode = rxAlgorithm.cap(3).toLower();
- QString padding = rxAlgorithm.cap(4).toLower();
-
- QCA::KeyGenerator keygen;
-
- // determine the discrete logarithm group to use
- QCA::DLGroupSet groupnum;
- switch (rxAlgorithm.cap(1).toInt()) {
- case 768:
- groupnum = QCA::IETF_768;
- break;
- case 1024:
- groupnum = QCA::IETF_1024;
- break;
- case 1536:
- groupnum = QCA::IETF_1536;
- break;
- case 2048:
- groupnum = QCA::IETF_2048;
- break;
- case 3072:
- groupnum = QCA::IETF_3072;
- break;
- case 4096:
- groupnum = QCA::IETF_4096;
- break;
- case 6144:
- groupnum = QCA::IETF_6144;
- break;
- case 8192:
- groupnum = QCA::IETF_8192;
- break;
- default:
- // no known discrete logarithm group
- return 0;
- }
- QCA::DLGroup dlgroup(keygen.createDLGroup(groupnum));
- if (dlgroup.isNull()) {
- return 0;
- }
-
- // determine if we support (or want to support)
- // the encryption algorithm.
- if ((encalgo == "blowfish" || encalgo == "twofish" ||
- encalgo == "aes128" || encalgo == "aes192" ||
- encalgo == "aes256") &&
- QCA::isSupported(QString("%1-%2-%3").arg(encalgo, blockmode, padding)
- .toLatin1().constData())) {
-
- // get client's public key
- QCA::DHPublicKey clientKey(dlgroup,
- \
QCA::BigInteger(QCA::SecureArray(input.toByteArray())));
- // generate own private key
- QCA::PrivateKey privKey(keygen.createDH(dlgroup));
- // generate the shared symmetric key
- QCA::SymmetricKey sharedKey(privKey.deriveKey(clientKey));
-
- QCA::Cipher::Mode cbm;
- if (blockmode == "cbc") {
- cbm = QCA::Cipher::CBC;
- } else {
- return 0;
- }
-
- QCA::Cipher::Padding cp;
- if (padding == "pkcs7") {
- cp = QCA::Cipher::PKCS7;
- } else if (padding == "default") {
- cp = QCA::Cipher::DefaultPadding;
- } else {
- return 0;
- }
-
- QCA::Cipher *cipher = new QCA::Cipher(encalgo, cbm, cp);
-
- // check if creating the cipher worked and if our shared
- // key is longer than the minimum length required.
- if (sharedKey.size() >= cipher->keyLength().minimum()) {
- // generate the response to the client so it can derive
- // the key as well.
- session = new Session(parent);
- session->m_encrypted = true;
- session->m_cipher = cipher;
- session->m_symmetricKey = sharedKey;
- output.setValue(privKey.toPublicKey().toDH().y().toArray().toByteArray());
- } else {
- return 0;
- }
- }
- } else {
- return 0;
- }
-
- // creating the session was successful
- session->m_peer = peer;
- return session;
-}
-
-Secret Session::encrypt(const QCA::SecureArray &value, bool &ok)
-{
- ok = false;
-
- Secret s;
- s.setSession(m_objectPath);
- if (m_encrypted) {
- Q_ASSERT(m_cipher);
- QCA::InitializationVector iv(m_cipher->blockSize());
- m_cipher->setup(QCA::Encode, m_symmetricKey, iv);
- QCA::SecureArray encval = m_cipher->update(value);
- if (!m_cipher->ok()) {
- return s;
- }
- encval += m_cipher->final();
- if (m_cipher->ok()) {
- return s;
- }
- s.setValue(encval.toByteArray());
- s.setParameters(iv.toByteArray());
- } else {
- s.setValue(value.toByteArray());
- }
-
-
- ok = true;
- return s;
-}
-
-QCA::SecureArray Session::decrypt(const Secret &secret, bool &ok)
-{
- // make sure this is really meant for us
- Q_ASSERT(secret.session() == m_objectPath);
- ok = false;
-
- QCA::SecureArray value;
- if (m_encrypted) {
- Q_ASSERT(m_cipher);
- if (!secret.parameters().size() == m_cipher->blockSize()) {
- return value;
- }
- QCA::InitializationVector iv(secret.parameters());
- m_cipher->setup(QCA::Decode, m_symmetricKey, iv);
- value = m_cipher->update(secret.value());
- if (!m_cipher->ok()) {
- return value;
- }
- value += m_cipher->final();
- if (!m_cipher->ok()) {
- return value;
- }
- } else {
- value = secret.value();
- }
-
- ok = true;
- return value;
-}
-
-void Session::close()
-{
- deleteLater();
-}
-
-const QString &Session::peer() const
-{
- return m_peer;
-}
-
-#include "session.moc"
diff --git a/daemon/session.h b/daemon/session.h
deleted file mode 100644
index e2cb335..0000000
--- a/daemon/session.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAEMON_SESSION_H
-#define DAEMON_SESSION_H
-
-#include "secret.h"
-
-#include <QtCore/QObject>
-#include <QtCrypto/QtCrypto>
-
-class Service;
-
-/**
- * Represents an open session of a client on the D-Bus implementing the
- * org.freedesktop.Secret.Session interface.
- *
- * @todo stub implementation, currently only supports plain (no encryption)
- */
-class Session : public QObject
-{
- Q_OBJECT
-
-private:
- /**
- * Constructor.
- *
- * @param parent Parent Service object
- */
- Session(Service *parent);
-
-public:
- /**
- * Destructor.
- */
- ~Session();
-
- /**
- * Get the session's object path.
- */
- const QDBusObjectPath &objectPath() const;
-
- /**
- * Try to create a (possibly encrypted) session for the use of transferring
- * secrets.
- *
- * @param algorithm the negotiation/encryption algorithm to use
- * @param input negotiation algorithm input
- * @param output negotiation algorithm output
- * @param parent Parent Service object
- * @return a session object if negotiation was successful, 0 if the algorithm \
isn't
- * supported or an error occurred
- */
- static Session *create(const QString &algorithm, const QVariant &input,
- QVariant &output, const QString &peer, Service *parent);
-
- /**
- * Encrypt a secret value using this session.
- *
- * @param value value to encrypt
- * @param ok set to true if encrypting succeeds, set to false else
- * @return the secret encrypted for transport
- */
- Secret encrypt(const QCA::SecureArray &value, bool &ok);
-
- /**
- * Decrypt a secret value using this session.
- *
- * @param secret Secret received on the D-Bus
- * @param ok set to true if decrypting succeeds, set to false else
- * @return the unencryped value
- */
- QCA::SecureArray decrypt(const Secret &secret, bool &ok);
-
- /**
- * Close this session.
- */
- void close();
-
- /**
- * Get the session's D-Bus peer (the client requesting the session).
- */
- const QString &peer() const;
-
-private:
- QDBusObjectPath m_objectPath;
- QString m_peer; // D-Bus address of the application that requested this session
-
- // if true, use encryption, if false, use plaintext
- bool m_encrypted;
-
- // the cipher and the symmetric key used for encryption
- QCA::Cipher *m_cipher;
- QCA::SymmetricKey m_symmetricKey;
-};
-
-#endif
diff --git a/daemon/tests/CMakeLists.txt b/daemon/tests/CMakeLists.txt
deleted file mode 100644
index 04029ff..0000000
--- a/daemon/tests/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-SET (EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
-
-INCLUDE_DIRECTORIES (
- ${KDE4_INCLUDES}
- ${QCA2_INCLUDE_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}
-)
-
-KDE4_ADD_EXECUTABLE (ksecretservice_daemon_test
- servicetest.cpp
- tempblockingcollectionmanager.cpp
- tempblockingcollection.cpp
- tempblockingitem.cpp
- tempblockingjobs.cpp
-)
-TARGET_LINK_LIBRARIES (ksecretservice_daemon_test
- ksecretservicebackend
- ksecretservicedaemon
- ksecretservicelib
- ${QT_QTTEST_LIBRARIES}
-)
-
-ADD_TEST (DaemonSessionTest ksecretservice_daemon_test)
diff --git a/daemon/tests/servicetest.cpp b/daemon/tests/servicetest.cpp
deleted file mode 100644
index 000dcc4..0000000
--- a/daemon/tests/servicetest.cpp
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "servicetest.h"
-
-#include "backend/backendmaster.h"
-#include "backend/temporary/temporarycollectionmanager.h"
-#include "tempblockingcollectionmanager.h"
-#include "daemon/service.h"
-#include "daemon/dbus/dbustypes.h"
-
-#include <qtest_kde.h>
-
-#include <QtTest/QTest>
-#include <QtDBus/QDBusConnection>
-#include <QtDBus/QDBusInterface>
-#include <QtDBus/QDBusMessage>
-#include <QtDBus/QDBusReply>
-#include <QtDBus/QDBusConnectionInterface>
-#include <QtCrypto/QtCrypto>
-
-#include <QtCore/QDebug>
-
-void ServiceTest::initTestCase()
-{
- QVERIFY(QDBusConnection::sessionBus().registerService("org.freedesktop.Secret"));
-
- QCA::init();
-
- m_master = new BackendMaster;
- m_tempCollMan = new TemporaryCollectionManager(m_master);
- m_master->addManager(m_tempCollMan);
- m_service = new Service(m_master);
-}
-
-void ServiceTest::dbusService()
-{
- // make sure the service is available
- QDBusConnectionInterface *ifaceConn = QDBusConnection::sessionBus().interface();
- QVERIFY(ifaceConn && ifaceConn->isValid());
-
- QDBusReply<bool> registered = \
ifaceConn->isServiceRegistered("org.freedesktop.Secret");
- QVERIFY(registered.isValid());
- QVERIFY(registered.value());
-}
-
-void ServiceTest::session()
-{
- QDBusInterface ifaceService("org.freedesktop.Secret", \
"/org/freedesktop/secrets");
- QVERIFY(ifaceService.isValid());
- QCA::KeyGenerator keygen;
-
- // "unsupported" session algorithm
- QList<QVariant> unsuppInput;
- unsuppInput << QString("unsupported") << \
QVariant::fromValue(QDBusVariant(QString("")));
- QDBusMessage unsuppReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession",
- unsuppInput);
- QCOMPARE(unsuppReply.type(), QDBusMessage::ErrorMessage);
- QCOMPARE(unsuppReply.errorName(),
- QLatin1String("org.freedesktop.Secret.Error.NotSupported"));
-
- // "plain" session algorithm
- QDBusObjectPath plainPath;
- QList<QVariant> plainInput;
- plainInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
- QDBusMessage plainReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession",
- plainInput);
- QCOMPARE(plainReply.type(), QDBusMessage::ReplyMessage);
- QList<QVariant> plainArgs = plainReply.arguments();
- QCOMPARE(plainArgs.size(), 2);
- QCOMPARE(plainArgs.at(0).userType(), qMetaTypeId<QDBusVariant>());
- QCOMPARE(plainArgs.at(0).value<QString>(), QLatin1String(""));
- QCOMPARE(plainArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
- plainPath = plainArgs.at(1).value<QDBusObjectPath>();
- QVERIFY(plainPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/session/")));
- QDBusInterface plainIface("org.freedesktop.Secret", plainPath.path(),
- "org.freedesktop.Secret.Session");
- QVERIFY(plainIface.isValid());
- QDBusMessage plainReply2 = plainIface.call("Close");
- QCOMPARE(plainReply2.type(), QDBusMessage::ReplyMessage);
- QCOMPARE(plainIface.call("Introspect").type(), QDBusMessage::ErrorMessage);
-
- // "dh-ietf1024-aes128-cbc-pkcs7" encryption
- QDBusObjectPath dhPath;
- QList<QVariant> dhInput;
- QCA::DLGroup dhDlgroup(keygen.createDLGroup(QCA::IETF_1024));
- QVERIFY(!dhDlgroup.isNull());
- QCA::PrivateKey dhPrivkey(keygen.createDH(dhDlgroup));
- QCA::PublicKey dhPubkey(dhPrivkey);
- QByteArray dhBytePub(dhPubkey.toDH().y().toArray().toByteArray());
- dhInput << QString("dh-ietf1024-aes128-cbc-pkcs7")
- << QVariant::fromValue(QDBusVariant(dhBytePub));
- QDBusMessage dhReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession",
- dhInput);
- QCOMPARE(dhReply.type(), QDBusMessage::ReplyMessage);
- QList<QVariant> dhArgs = dhReply.arguments();
- QCOMPARE(dhArgs.size(), 2);
- QCOMPARE(dhArgs.at(0).userType(), qMetaTypeId<QDBusVariant>());
- QVariant dhOutputVar = dhArgs.at(0).value<QDBusVariant>().variant();
- QCOMPARE(dhOutputVar.type(), QVariant::ByteArray);
- QByteArray dhOutput = dhOutputVar.toByteArray();
- QCA::DHPublicKey dhServiceKey(dhDlgroup,
- QCA::BigInteger(QCA::SecureArray(dhOutput)));
- QCA::SymmetricKey dhSharedKey(dhPrivkey.deriveKey(dhServiceKey));
- QCA::Cipher *dhCipher = new QCA::Cipher("aes128", QCA::Cipher::CBC, \
QCA::Cipher::PKCS7);
- QVERIFY(dhSharedKey.size() >= dhCipher->keyLength().minimum());
- QCOMPARE(plainArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
- dhPath = dhArgs.at(1).value<QDBusObjectPath>();
- QVERIFY(dhPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/session/")));
- QDBusInterface dhIface("org.freedesktop.Secret", dhPath.path(),
- "org.freedesktop.Secret.Session");
- QVERIFY(dhIface.isValid());
- QDBusMessage dhReply2 = dhIface.call("Close");
- QCOMPARE(dhReply2.type(), QDBusMessage::ReplyMessage);
- QCOMPARE(dhIface.call("Introspect").type(), QDBusMessage::ErrorMessage);
-}
-
-void ServiceTest::nonBlockingCollection()
-{
- QDBusInterface ifaceService("org.freedesktop.Secret", \
"/org/freedesktop/secrets");
- QVERIFY(ifaceService.isValid());
-
- // create a session
- QDBusObjectPath sessionPath;
- QList<QVariant> sessionInput;
- sessionInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
- QDBusMessage sessionReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession",
- sessionInput);
- sessionPath = sessionReply.arguments().at(1).value<QDBusObjectPath>();
-
- // listen to CollectionCreated/CollectionDeleted/CollectionChanged signals
- ObjectPathSignalSpy createdSpy(&ifaceService, \
SIGNAL(CollectionCreated(QDBusObjectPath)));
- QVERIFY(createdSpy.isValid());
- ObjectPathSignalSpy deletedSpy(&ifaceService, \
SIGNAL(CollectionDeleted(QDBusObjectPath)));
- QVERIFY(deletedSpy.isValid());
- ObjectPathSignalSpy changedSpy(&ifaceService, \
SIGNAL(CollectionChanged(QDBusObjectPath)));
- QVERIFY(changedSpy.isValid());
-
- // create a collection
- QDBusObjectPath collectionPath;
- QMap<QString, QVariant> createProperties;
- QList<QVariant> createInput;
- createProperties["Label"] = "test";
- createProperties["Locked"] = false; // create collection unlocked
- createInput << QVariant::fromValue(createProperties);
- QDBusMessage createReply = ifaceService.callWithArgumentList(QDBus::Block, \
"CreateCollection",
- createInput);
-
- QCOMPARE(createReply.type(), QDBusMessage::ReplyMessage);
- QList<QVariant> createArgs = createReply.arguments();
- QCOMPARE(createArgs.size(), 2);
- QCOMPARE(createArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
- QCOMPARE(createArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
- // CreateCollection is blocking, so the first output (path) should be "/".
- QCOMPARE(createArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
- QDBusObjectPath promptPath = createArgs.at(1).value<QDBusObjectPath>();
- QVERIFY(promptPath.path().startsWith(
- QLatin1String("/org/freedesktop/secrets/prompts/")));
-
- // prompt and wait for the result.
- ClientPrompt *prompt = new ClientPrompt(promptPath);
- prompt->promptAndWait(5000);
- QVERIFY(prompt->completed());
- QVERIFY(!prompt->dismissed());
- QCOMPARE(prompt->result().userType(), qMetaTypeId<QDBusObjectPath>());
- collectionPath = prompt->result().value<QDBusObjectPath>();
- QVERIFY(collectionPath.path().startsWith(
- QLatin1String("/org/freedesktop/secrets/collection/")));
- QDBusInterface ifaceCollection("org.freedesktop.Secret", collectionPath.path(),
- "org.freedesktop.Secret.Collection");
- QVERIFY(ifaceCollection.isValid());
- delete prompt;
-
- // make sure the CollectionCreated signal was sent
- if (createdSpy.size() < 1) {
- createdSpy.waitForSignal(5000);
- }
- QCOMPARE(createdSpy.size(), 1);
- QCOMPARE(createdSpy.takeFirst(), collectionPath);
-
- // read collection properties
- QVariant propItems = ifaceCollection.property("Items");
- QVERIFY(propItems.isValid());
- QVERIFY(propItems.canConvert<QList<QDBusObjectPath> >());
- QList<QDBusObjectPath> propItemsList = propItems.value<QList<QDBusObjectPath> \
>();
- QVERIFY(propItemsList.isEmpty());
- QVariant propLabel = ifaceCollection.property("Label");
- QVERIFY(propLabel.isValid());
- QCOMPARE(propLabel.type(), QVariant::String);
- QCOMPARE(propLabel.value<QString>(), QString("test"));
- QVariant propLocked = ifaceCollection.property("Locked");
- QVERIFY(propLocked.isValid());
- QCOMPARE(propLocked.value<bool>(), false);
- QVariant propCreated = ifaceCollection.property("Created");
- QVERIFY(propCreated.isValid());
- QCOMPARE(propCreated.type(), QVariant::ULongLong);
- qulonglong propCreatedUll = propCreated.value<qulonglong>();
- QVERIFY(QDateTime::currentDateTime().toTime_t() - propCreatedUll < 60);
- QVariant propModified = ifaceCollection.property("Modified");
- QVERIFY(propModified.isValid());
- QCOMPARE(propModified.type(), QVariant::ULongLong);
- QCOMPARE(propModified.value<qulonglong>(), propCreatedUll);
-
- // set the label and re-read it.
- ifaceCollection.setProperty("Label", QString("test2"));
- propLabel = ifaceCollection.property("Label");
- QVERIFY(propLabel.isValid());
- QCOMPARE(propLabel.type(), QVariant::String);
- QCOMPARE(propLabel.value<QString>(), QString("test2"));
-
- // make sure the CollectionChanged signal was sent
- if (changedSpy.size() < 1) {
- changedSpy.waitForSignal(5000);
- }
- QCOMPARE(changedSpy.size(), 1);
- QCOMPARE(changedSpy.takeFirst(), collectionPath);
-
- // delete the collection
- QDBusMessage deleteReply = ifaceCollection.call(QDBus::Block, "Delete");
- QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
- QList<QVariant> deleteArgs = deleteReply.arguments();
- QCOMPARE(deleteArgs.size(), 1);
- QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
- // TemporaryCollection is non-blocking, so the output (prompt) should be "/".
- QCOMPARE(deleteArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
- // make sure the collection is gone
- QCOMPARE(ifaceCollection.call("Introspect").type(), QDBusMessage::ErrorMessage);
-
- // make sure the CollectionDeleted signal was sent
- if (deletedSpy.size() < 1) {
- deletedSpy.waitForSignal(5000);
- }
- QCOMPARE(deletedSpy.size(), 1);
- QCOMPARE(deletedSpy.takeFirst(), collectionPath);
-
- // close the session
- QDBusInterface("org.freedesktop.Secret", sessionPath.path()).call("Close");
-}
-
-void ServiceTest::nonBlockingItem()
-{
- QDBusInterface ifaceService("org.freedesktop.Secret", \
"/org/freedesktop/secrets");
-
- // create a session
- QDBusObjectPath sessionPath;
- QList<QVariant> sessionInput;
- sessionInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
- QDBusMessage sessionReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession",
- sessionInput);
- sessionPath = sessionReply.arguments().at(1).value<QDBusObjectPath>();
-
- // create a collection
- QDBusObjectPath collectionPath;
- QMap<QString, QVariant> collProperties;
- QList<QVariant> collInput;
- collProperties["Label"] = "test3";
- collProperties["Locked"] = false;
- collInput << QVariant::fromValue(collProperties);
- QDBusMessage collReply = ifaceService.callWithArgumentList(QDBus::Block, \
"CreateCollection",
- collInput);
- QDBusObjectPath promptPath = \
collReply.arguments().at(1).value<QDBusObjectPath>();
- ClientPrompt *prompt = new ClientPrompt(promptPath);
- prompt->promptAndWait(5000);
- QVERIFY(prompt->completed());
- collectionPath = prompt->result().value<QDBusObjectPath>();
- delete prompt;
- QDBusInterface ifaceColl("org.freedesktop.Secret", collectionPath.path());
-
- ObjectPathSignalSpy createdSpy(&ifaceColl, SIGNAL(ItemCreated(QDBusObjectPath)));
- QVERIFY(createdSpy.isValid());
- ObjectPathSignalSpy deletedSpy(&ifaceColl, SIGNAL(ItemDeleted(QDBusObjectPath)));
- QVERIFY(deletedSpy.isValid());
- ObjectPathSignalSpy changedSpy(&ifaceColl, SIGNAL(ItemChanged(QDBusObjectPath)));
- QVERIFY(changedSpy.isValid());
-
- // create an item
- QDBusObjectPath itemPath;
- StringStringMap itemAttributes;
- itemAttributes["attribute1"] = "value1";
- itemAttributes["attribute2"] = "value2";
- QMap<QString, QVariant> itemProperties;
- itemProperties["Attributes"] = QVariant::fromValue(itemAttributes);
- itemProperties["Label"] = "item1";
- itemProperties["Locked"] = false;
- QList<QVariant> itemInput;
- Secret secret;
- secret.setSession(sessionPath);
- secret.setValue(QByteArray("mysecret"));
- itemInput << QVariant::fromValue(itemProperties);
- itemInput << QVariant::fromValue(secret);
- itemInput << false;
- QDBusMessage itemReply = ifaceColl.callWithArgumentList(QDBus::Block, \
"CreateItem",
- itemInput);
- QCOMPARE(itemReply.type(), QDBusMessage::ReplyMessage);
- QList<QVariant> itemArgs = itemReply.arguments();
- QCOMPARE(itemArgs.size(), 2);
- QCOMPARE(itemArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
- QCOMPARE(itemArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
- // TemporaryItem is non-blocking, so the second output (prompt) should be "/"
- QCOMPARE(itemArgs.at(1).value<QDBusObjectPath>().path(), QLatin1String("/"));
- itemPath = itemArgs.at(0).value<QDBusObjectPath>();
- QVERIFY(itemPath.path().startsWith(collectionPath.path() + "/"));
- QDBusInterface ifaceItem("org.freedesktop.Secret", itemPath.path(),
- "org.freedesktop.Secret.Item");
- QVERIFY(ifaceItem.isValid());
-
- // make sure the ItemCreated signal was sent
- if (createdSpy.size() < 1) {
- createdSpy.waitForSignal(5000);
- }
- QCOMPARE(createdSpy.size(), 1);
- QCOMPARE(createdSpy.takeFirst(), itemPath);
-
- // check if the collection's Items property contains the item.
- QVariant propItems = ifaceColl.property("Items");
- QVERIFY(propItems.isValid());
- QVERIFY(propItems.canConvert<QList<QDBusObjectPath> >());
- QList<QDBusObjectPath> propItemsList = propItems.value<QList<QDBusObjectPath> \
>();
- QCOMPARE(propItemsList.count(), 1);
- QCOMPARE(propItemsList.at(0), itemPath);
-
- // read item properties
- QVariant propLocked = ifaceItem.property("Locked");
- QVERIFY(propLocked.isValid());
- QCOMPARE(propLocked.type(), QVariant::Bool);
- QCOMPARE(propLocked.value<bool>(), false);
- QVariant propLabel = ifaceItem.property("Label");
- QVERIFY(propLabel.isValid());
- QCOMPARE(propLabel.type(), QVariant::String);
- QCOMPARE(propLabel.value<QString>(), QLatin1String("item1"));
- QVariant propCreated = ifaceItem.property("Created");
- QVERIFY(propCreated.isValid());
- QCOMPARE(propCreated.type(), QVariant::ULongLong);
- qulonglong propCreatedUll = propCreated.value<qulonglong>();
- QVERIFY(QDateTime::currentDateTime().toTime_t() - propCreatedUll < 60);
- QVariant propModified = ifaceItem.property("Modified");
- QVERIFY(propModified.isValid());
- QCOMPARE(propModified.type(), QVariant::ULongLong);
- QCOMPARE(propModified.value<qulonglong>(), propCreatedUll);
- QVariant propAttributes = ifaceItem.property("Attributes");
- QVERIFY(propAttributes.isValid());
- QCOMPARE(propAttributes.userType(), qMetaTypeId<StringStringMap>());
- StringStringMap propAttributesMap = propAttributes.value<StringStringMap>();
- QCOMPARE(propAttributesMap.size(), 2);
- QCOMPARE(propAttributesMap.value("attribute1"), QLatin1String("value1"));
- QCOMPARE(propAttributesMap.value("attribute2"), QLatin1String("value2"));
-
- // read the secret
- QDBusMessage secretReply = ifaceItem.call(QDBus::Block, "GetSecret",
- \
QVariant::fromValue<QDBusObjectPath>(sessionPath));
- QCOMPARE(secretReply.type(), QDBusMessage::ReplyMessage);
- QList<QVariant> secretOutput = secretReply.arguments();
- QCOMPARE(secretOutput.count(), 1);
- Secret outsecret = qdbus_cast<Secret>(secretOutput.at(0));
- QCOMPARE(outsecret.session(), sessionPath);
- QCOMPARE(outsecret.value(), QByteArray("mysecret"));
-
- // set and re-read item properties
- ifaceItem.setProperty("Label", QString("item2"));
- propLabel = ifaceItem.property("Label");
- QVERIFY(propLabel.isValid());
- QCOMPARE(propLabel.type(), QVariant::String);
- QCOMPARE(propLabel.value<QString>(), QLatin1String("item2"));
- propAttributesMap["attribute3"] = "value3";
- propAttributesMap["attribute1"] = "othervalue";
- propAttributesMap.remove("attribute2");
- ifaceItem.setProperty("Attributes", \
QVariant::fromValue<StringStringMap>(propAttributesMap));
- propAttributes = ifaceItem.property("Attributes");
- QVERIFY(propAttributes.isValid());
- QCOMPARE(propAttributes.userType(), qMetaTypeId<StringStringMap>());
- propAttributesMap = propAttributes.value<StringStringMap>();
- QCOMPARE(propAttributesMap.size(), 2);
- QCOMPARE(propAttributesMap.value("attribute1"), QLatin1String("othervalue"));
- QCOMPARE(propAttributesMap.value("attribute3"), QLatin1String("value3"));
-
- // set and re-read the secret
- secret.setValue("mysecret2");
- secretReply = ifaceItem.call(QDBus::Block, "SetSecret", \
QVariant::fromValue<Secret>(secret));
- QCOMPARE(secretReply.type(), QDBusMessage::ReplyMessage);
- secretReply = ifaceItem.call(QDBus::Block, "GetSecret",
- QVariant::fromValue<QDBusObjectPath>(sessionPath));
- QCOMPARE(secretReply.type(), QDBusMessage::ReplyMessage);
- secretOutput = secretReply.arguments();
- QCOMPARE(secretOutput.count(), 1);
- outsecret = qdbus_cast<Secret>(secretOutput.at(0));
- QCOMPARE(outsecret.session(), sessionPath);
- QCOMPARE(outsecret.value(), QByteArray("mysecret2"));
-
-
- // we should have received 2 ItemChanged signals
- if (changedSpy.size() < 3) {
- changedSpy.waitForSignals(3, 5000);
- }
- QCOMPARE(changedSpy.size(), 3);
- QCOMPARE(changedSpy.takeFirst(), itemPath);
- QCOMPARE(changedSpy.takeFirst(), itemPath);
- QCOMPARE(changedSpy.takeFirst(), itemPath);
-
- // delete the item
- QDBusMessage deleteReply = ifaceItem.call(QDBus::Block, "Delete");
- QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
- QList<QVariant> deleteArgs = deleteReply.arguments();
- QCOMPARE(deleteArgs.size(), 1);
- QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
- // TemporaryItem is non-blocking, so the output (prompt) should be "/"
- QCOMPARE(deleteArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
- // make sure the item is gone
- QCOMPARE(ifaceItem.call("Introspect").type(), QDBusMessage::ErrorMessage);
-
- // make sure the ItemDeleted signal was sent
- if (deletedSpy.size() < 1) {
- deletedSpy.waitForSignal(5000);
- }
- QCOMPARE(deletedSpy.size(), 1);
- QCOMPARE(deletedSpy.takeFirst(), itemPath);
-
- // delete the collection
- ifaceColl.call(QDBus::Block, "Delete");
- // close the session
- QDBusInterface("org.freedesktop.Secret", sessionPath.path()).call("Close");
-}
-
-void ServiceTest::reInitTestCase()
-{
- // remove the TemporaryCollectionManager and replace it with a \
TempBlockingCollectionManager
- m_master->removeManager(m_tempCollMan);
- delete m_tempCollMan;
- m_tempBlockCollMan = new TempBlockingCollectionManager(m_master);
- m_master->addManager(m_tempBlockCollMan);
-}
-
-void ServiceTest::blockingCollection()
-{
- ClientPrompt *prompt = 0;
-
- QDBusInterface ifaceService("org.freedesktop.Secret", \
"/org/freedesktop/secrets");
- QVERIFY(ifaceService.isValid());
-
- // create a session
- // create a session
- QDBusObjectPath sessionPath;
- QList<QVariant> sessionInput;
- sessionInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
- QDBusMessage sessionReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession",
- sessionInput);
- sessionPath = sessionReply.arguments().at(1).value<QDBusObjectPath>();
-
- // listen to CollectionCreated/CollectionDeleted/CollectionChanged signals
- ObjectPathSignalSpy createdSpy(&ifaceService, \
SIGNAL(CollectionCreated(QDBusObjectPath)));
- QVERIFY(createdSpy.isValid());
- ObjectPathSignalSpy deletedSpy(&ifaceService, \
SIGNAL(CollectionDeleted(QDBusObjectPath)));
- QVERIFY(deletedSpy.isValid());
- ObjectPathSignalSpy changedSpy(&ifaceService, \
SIGNAL(CollectionChanged(QDBusObjectPath)));
- QVERIFY(changedSpy.isValid());
-
- // create a collection
- QDBusObjectPath promptPath;
- QMap<QString, QVariant> createProperties;
- QList<QVariant> createInput;
- createProperties["Label"] = "test";
- createProperties["Locked"] = false; // create collection unlocked
- createInput << QVariant::fromValue(createProperties);
- QDBusMessage createReply = ifaceService.callWithArgumentList(QDBus::Block, \
"CreateCollection",
- createInput);
- QCOMPARE(createReply.type(), QDBusMessage::ReplyMessage);
- QList<QVariant> createArgs = createReply.arguments();
- QCOMPARE(createArgs.size(), 2);
- QCOMPARE(createArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
- QCOMPARE(createArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
- // TempBlockingCollection is blocking, so the first output (path) should be "/".
- QCOMPARE(createArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
- promptPath = createArgs.at(1).value<QDBusObjectPath>();
- QVERIFY(promptPath.path().startsWith(
- QLatin1String("/org/freedesktop/secrets/prompts/")));
-
- // dismiss the prompt and wait for the result.
- prompt = new ClientPrompt(promptPath);
- prompt->dismissAndWait(5000);
- QVERIFY(prompt->completed());
- QVERIFY(prompt->dismissed());
- delete prompt;
-
- createReply = ifaceService.callWithArgumentList(QDBus::Block, "CreateCollection",
- createInput);
- QCOMPARE(createReply.type(), QDBusMessage::ReplyMessage);
- createArgs = createReply.arguments();
- QCOMPARE(createArgs.size(), 2);
- QCOMPARE(createArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
- QCOMPARE(createArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
- // TempBlockingCollection is blocking, so the first output (path) should be "/".
- QCOMPARE(createArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
- promptPath = createArgs.at(1).value<QDBusObjectPath>();
- QVERIFY(promptPath.path().startsWith(
- QLatin1String("/org/freedesktop/secrets/prompts/")));
-
- // prompt and wait for the result.
- prompt = new ClientPrompt(promptPath);
- prompt->promptAndWait(5000);
- QVERIFY(prompt->completed());
- QVERIFY(!prompt->dismissed());
- QCOMPARE(prompt->result().userType(), qMetaTypeId<QDBusObjectPath>());
- QDBusObjectPath collectionPath = prompt->result().value<QDBusObjectPath>();
- QVERIFY(collectionPath.path().startsWith(
- QLatin1String("/org/freedesktop/secrets/collection/")));
- QDBusInterface ifaceCollection("org.freedesktop.Secret", collectionPath.path(),
- "org.freedesktop.Secret.Collection");
- QVERIFY(ifaceCollection.isValid());
- delete prompt;
-
- // make sure the CollectionCreated signal was sent
- if (createdSpy.size() < 1) {
- createdSpy.waitForSignal(5000);
- }
- QCOMPARE(createdSpy.size(), 1);
- QCOMPARE(createdSpy.takeFirst(), collectionPath);
-
- // read collection properties
- QVariant propItems = ifaceCollection.property("Items");
- QVERIFY(propItems.isValid());
- QVERIFY(propItems.canConvert<QList<QDBusObjectPath> >());
- QList<QDBusObjectPath> propItemsList = propItems.value<QList<QDBusObjectPath> \
>();
- QVERIFY(propItemsList.isEmpty());
- QVariant propLabel = ifaceCollection.property("Label");
- QVERIFY(propLabel.isValid());
- QCOMPARE(propLabel.type(), QVariant::String);
- QCOMPARE(propLabel.value<QString>(), QString("test"));
- QVariant propLocked = ifaceCollection.property("Locked");
- QVERIFY(propLocked.isValid());
- QCOMPARE(propLocked.value<bool>(), false);
- QVariant propCreated = ifaceCollection.property("Created");
- QVERIFY(propCreated.isValid());
- QCOMPARE(propCreated.type(), QVariant::ULongLong);
- qulonglong propCreatedUll = propCreated.value<qulonglong>();
- QVERIFY(QDateTime::currentDateTime().toTime_t() - propCreatedUll < 60);
- QVariant propModified = ifaceCollection.property("Modified");
- QVERIFY(propModified.isValid());
- QCOMPARE(propModified.type(), QVariant::ULongLong);
- QCOMPARE(propModified.value<qulonglong>(), propCreatedUll);
-
- // set the label and re-read it.
- ifaceCollection.setProperty("Label", QString("test2"));
- propLabel = ifaceCollection.property("Label");
- QVERIFY(propLabel.isValid());
- QCOMPARE(propLabel.type(), QVariant::String);
- QCOMPARE(propLabel.value<QString>(), QString("test2"));
-
- // make sure the CollectionChanged signal was sent
- if (changedSpy.size() < 1) {
- changedSpy.waitForSignal(5000);
- }
- QCOMPARE(changedSpy.size(), 1);
- QCOMPARE(changedSpy.takeFirst(), collectionPath);
-
- // delete the collection
- QDBusMessage deleteReply = ifaceCollection.call(QDBus::Block, "Delete");
- QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
- QList<QVariant> deleteArgs = deleteReply.arguments();
- QCOMPARE(deleteArgs.size(), 1);
- QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
- // TempBlockingCollection is blocking, so the output (prompt) should be a valid \
one.
- promptPath = deleteArgs.at(0).value<QDBusObjectPath>();
- QVERIFY(promptPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/prompts/")));
-
- // dismiss the prompt and wait for the result.
- prompt = new ClientPrompt(promptPath);
- prompt->dismissAndWait(5000);
- QVERIFY(prompt->completed());
- QVERIFY(prompt->dismissed());
- delete prompt;
-
- // retry and complete the prompt this time
- deleteReply = ifaceCollection.call(QDBus::Block, "Delete");
- QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
- deleteArgs = deleteReply.arguments();
- QCOMPARE(deleteArgs.size(), 1);
- QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
- // TempBlockingCollection is blocking, so the output (prompt) should be a valid \
one.
- promptPath = deleteArgs.at(0).value<QDBusObjectPath>();
- QVERIFY(promptPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/prompts/")));
- prompt = new ClientPrompt(promptPath);
- prompt->promptAndWait(5000);
- QVERIFY(prompt->completed());
- QVERIFY(!prompt->dismissed());
- delete prompt;
-
- // make sure the collection is gone
- QCOMPARE(ifaceCollection.call("Introspect").type(), QDBusMessage::ErrorMessage);
-
- // make sure the CollectionDeleted signal was sent
- if (deletedSpy.size() < 1) {
- deletedSpy.waitForSignal(5000);
- }
- QCOMPARE(deletedSpy.size(), 1);
- QCOMPARE(deletedSpy.takeFirst(), collectionPath);
-
- // close the session
- QDBusInterface("org.freedesktop.Secret", sessionPath.path()).call("Close");
-}
-
-void ServiceTest::blockingItem()
-{
- // TODO: test
-}
-
-void ServiceTest::cleanupTestCase()
-{
- delete m_service;
- delete m_master;
-
- QCA::deinit();
-}
-
-QTEST_KDEMAIN_CORE(ServiceTest)
-
-ObjectPathSignalSpy::ObjectPathSignalSpy(QDBusAbstractInterface *iface,
- const char *signal)
-{
- m_valid = connect(iface, signal, SLOT(slotReceived(QDBusObjectPath)));
-}
-
-bool ObjectPathSignalSpy::isValid() const
-{
- return m_valid;
-}
-
-void ObjectPathSignalSpy::waitForSignal(int time)
-{
- waitForSignals(1, time);
-}
-
-void ObjectPathSignalSpy::waitForSignals(int num, int time)
-{
- m_numWaiting = num;
- if (count() < m_numWaiting)
- {
- QEventLoop loop;
- loop.connect(this, SIGNAL(doneWaiting()), SLOT(quit()));
- QTimer::singleShot(time, &loop, SLOT(quit()));
- loop.exec();
- }
-}
-
-void ObjectPathSignalSpy::slotReceived(const QDBusObjectPath &objectPath)
-{
- append(objectPath);
- if (count() >= m_numWaiting) {
- emit doneWaiting();
- }
-}
-
-ClientPrompt::ClientPrompt(QDBusObjectPath promptPath)
- : m_completed(false), m_dismissed(false),
- m_interface("org.freedesktop.Secret", promptPath.path())
-{
- Q_ASSERT(m_interface.isValid());
- connect(&m_interface, SIGNAL(Completed(bool, QDBusVariant)),
- SLOT(slotCompleted(bool, QDBusVariant)));
-}
-
-void ClientPrompt::promptAndWait(int time)
-{
- QDBusMessage reply = m_interface.call(QDBus::Block, "Prompt", QString(""));
- Q_ASSERT(reply.type() == QDBusMessage::ReplyMessage);
- justWait(time);
-}
-
-void ClientPrompt::dismissAndWait(int time)
-{
- QDBusMessage reply = m_interface.call(QDBus::Block, "Dismiss");
- Q_ASSERT(reply.type() == QDBusMessage::ReplyMessage);
- justWait(time);
-}
-
-void ClientPrompt::slotCompleted(bool dismissed, const QDBusVariant &result)
-{
- m_completed = true;
- m_dismissed = dismissed;
- m_result = result.variant();
- m_loop.quit();
-}
-
-void ClientPrompt::justWait(int time)
-{
- if (time > 0) {
- QTimer::singleShot(time, &m_loop, SLOT(quit()));
- }
- m_loop.exec();
-}
-
-#include "servicetest.moc"
diff --git a/daemon/tests/servicetest.h b/daemon/tests/servicetest.h
deleted file mode 100644
index 4f9dbb3..0000000
--- a/daemon/tests/servicetest.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef SERVICETEST_H
-#define SERVICETEST_H
-
-#include <QtCore/QObject>
-#include <QtCore/QList>
-#include <QtCore/QVariant>
-#include <QtCore/QEventLoop>
-#include <QtDBus/QDBusVariant>
-#include <QtDBus/QDBusObjectPath>
-#include <QtDBus/QDBusInterface>
-
-class BackendMaster;
-class TemporaryCollectionManager;
-class TempBlockingCollectionManager;
-class Service;
-class QDBusAbstractInterface;
-
-/**
- * Unit-test for the fd.o Secret daemon
- */
-class ServiceTest : public QObject
-{
- Q_OBJECT
-
-private:
- BackendMaster *m_master;
- TemporaryCollectionManager *m_tempCollMan;
- TempBlockingCollectionManager *m_tempBlockCollMan;
- Service *m_service;
-
-private Q_SLOTS:
- // create services and collections needed for testing
- void initTestCase();
-
- // check if Service is registered with D-Bus
- void dbusService();
-
- // open various sessions, make sure they are available on the bus, then close \
them.
- void session();
-
- // create and remove collections
- void nonBlockingCollection();
-
- // create and remove items
- void nonBlockingItem();
-
- // change some of the parameters of the testcase needed for the tests to come
- void reInitTestCase();
-
- // create and remove blocking collections
- void blockingCollection();
-
- // create and remove blocking items
- void blockingItem();
-
- // cleanup
- void cleanupTestCase();
-};
-
-/**
- * Listens to D-Bus signals which only have an object-path
- * as only argument.
- */
-class ObjectPathSignalSpy : public QObject, public QList<QDBusObjectPath>
-{
- Q_OBJECT
-
-public:
- // constructor. similar to QSignalSpy's constructor.
- ObjectPathSignalSpy(QDBusAbstractInterface *iface, const char *signal);
-
- // return true if the connection to the signal was successful
- bool isValid() const;
-
- // wait a specified number of ms for the signal to be received.
- void waitForSignal(int time);
-
- // wait a specified number of ms for multiple signals to be received
- void waitForSignals(int num, int time);
-
-Q_SIGNALS:
- // stop waiting for the signal.
- void doneWaiting();
-
-private Q_SLOTS:
- // Single slot which receives all of the various signals.
- void slotReceived(const QDBusObjectPath &objectPath);
-
-private:
- bool m_valid;
- int m_numWaiting;
-};
-
-/**
- * Client mini-stub for org.freedesktop.Secret.Prompt.
- */
-class ClientPrompt : public QObject
-{
- Q_OBJECT
-
-public:
- // constructor. wraps around the prompt at promptPath.
- ClientPrompt(QDBusObjectPath promptPath);
-
- // Call the Prompt method and wait some time for completion
- // (sends bogus window-id)
- void promptAndWait(int time);
-
- // Call the Dismiss method and wait some time for completion
- void dismissAndWait(int time);
-
- // check if the call has been completed
- bool completed() const {
- return m_completed;
- }
-
- // check if the call was dismissed
- bool dismissed() const {
- return m_dismissed;
- }
-
- // get the call's result
- const QVariant &result() const {
- return m_result;
- }
-
-private Q_SLOTS:
- // listens for Completed signals of the D-Bus prompt.
- void slotCompleted(bool dismissed, const QDBusVariant &result);
-
-private:
- // just wait (called by *AndWait methods)
- void justWait(int time);
-
- bool m_completed;
- bool m_dismissed;
- QVariant m_result;
- QDBusInterface m_interface;
- QEventLoop m_loop;
-};
-
-#endif
diff --git a/daemon/tests/tempblockingcollection.cpp \
b/daemon/tests/tempblockingcollection.cpp deleted file mode 100644
index 8169aaa..0000000
--- a/daemon/tests/tempblockingcollection.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "tempblockingcollection.h"
-#include "tempblockingitem.h"
-#include "tempblockingjobs.h"
-
-#include <secrettool.h>
-
-TempBlockingCollection::TempBlockingCollection(const QString &id, \
BackendCollectionManager *parent)
- : BackendCollection(parent)
-{
- m_id = id;
- QDateTime now = QDateTime::currentDateTime();
- m_created = now;
- m_modified = now;
-}
-
-TempBlockingCollection::~TempBlockingCollection()
-{
-}
-
-QString TempBlockingCollection::id() const
-{
- return m_id;
-}
-
-BackendReturn<QString> TempBlockingCollection::label() const
-{
- return m_label;
-}
-
-BackendReturn<void> TempBlockingCollection::setLabel(const QString &label)
-{
- m_label = label;
- emit collectionChanged(this);
- return BackendReturn<void>();
-}
-
-QDateTime TempBlockingCollection::created() const
-{
- return m_created;
-}
-
-QDateTime TempBlockingCollection::modified() const
-{
- return m_modified;
-}
-
-bool TempBlockingCollection::isLocked() const
-{
- return false;
-}
-
-BackendReturn<QList<BackendItem*> > TempBlockingCollection::items() const
-{
- return m_items;
-}
-
-BackendReturn<QList<BackendItem*> > TempBlockingCollection::searchItems(
- const QMap<QString, QString> &attributes) const
-{
- TempBlockingItem *titem;
- QList<BackendItem*> foundItems;
- Q_FOREACH(BackendItem *item, m_items) {
- titem = qobject_cast<TempBlockingItem*>(item);
- if (titem && titem->matches(attributes)) {
- foundItems.append(item);
- }
- }
- return foundItems;
-}
-
-UnlockCollectionJob *TempBlockingCollection::createUnlockJob()
-{
- return new TempBlockingUnlockCollectionJob(this);
-}
-
-LockCollectionJob *TempBlockingCollection::createLockJob()
-{
- return new TempBlockingLockCollectionJob(this);
-}
-
-DeleteCollectionJob *TempBlockingCollection::createDeleteJob()
-{
- TempBlockingDeleteCollectionJob *job = new TempBlockingDeleteCollectionJob(this);
- connect(job, SIGNAL(result(QueuedJob*)),
- SLOT(deleteCollectionJobResult(QueuedJob*)));
- return job;
-}
-
-CreateItemJob *TempBlockingCollection::createCreateItemJob(const QString &label,
- const QMap<QString, \
QString> &attributes,
- const QCA::SecureArray \
&secret,
- bool locked, bool \
replace)
-{
- return new TempBlockingCreateItemJob(label, attributes, secret, locked, replace, \
this);
-}
-
-ChangeAuthenticationCollectionJob \
*TempBlockingCollection::createChangeAuthenticationJob()
-{
- return new TempBlockingChangeAuthenticationCollectionJob(this);
-}
-
-BackendReturn<BackendItem*> TempBlockingCollection::createItem(const QString &label,
- const QMap<QString, \
QString> &attributes,
- const \
QCA::SecureArray &secret,
- bool locked, bool \
replace)
-{
- Q_UNUSED(locked);
-
- TempBlockingItem *item = 0;
- bool replacing = false;
-
- // check for duplicates
- BackendReturn<QList<BackendItem*> > foundItems = searchItems(attributes);
- if (!foundItems.isError() && foundItems.value().size() > 0) {
- QList<BackendItem*> oldlist = foundItems.value();
- Q_FOREACH(BackendItem* olditem, oldlist) {
- if (olditem->attributes().value() == attributes) {
- if (replace) {
- // replacing an existing item
- item = qobject_cast<TempBlockingItem*>(olditem);
- replacing = true;
- } else {
- // item existing but should not be replaced
- return BackendReturn<BackendItem*>(0, ErrorAlreadyExists);
- }
- break;
- }
- }
- }
-
- if (!item) {
- item = new TempBlockingItem(createId(), this);
- }
- item->blockSignals(true);
- item->setLabel(label);
- item->setAttributes(attributes);
- item->setSecret(secret);
- item->blockSignals(false);
-
- if (replacing) {
- emit itemChanged(item);
- } else {
- m_items.append(item);
- // new item, signals need to be wired
- connect(item, SIGNAL(itemDeleted(BackendItem*)), \
SLOT(slotItemDeleted(BackendItem*)));
- connect(item, SIGNAL(itemChanged(BackendItem*)), \
SIGNAL(itemChanged(BackendItem*)));
- emit itemCreated(item);
- }
-
- return item;
-}
-
-void TempBlockingCollection::slotItemDeleted(BackendItem *item)
-{
- m_items.removeAll(item);
- emit itemDeleted(item);
-}
-
-void TempBlockingCollection::deleteCollectionJobResult(QueuedJob *job)
-{
- TempBlockingDeleteCollectionJob * dcj = \
qobject_cast<TempBlockingDeleteCollectionJob*>(job);
- Q_ASSERT(dcj);
- if (!dcj->result()) {
- return;
- }
- emit collectionDeleted(this);
-}
-
-#include "tempblockingcollection.moc"
diff --git a/daemon/tests/tempblockingcollection.h \
b/daemon/tests/tempblockingcollection.h deleted file mode 100644
index 7a71c2b..0000000
--- a/daemon/tests/tempblockingcollection.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TEMPBLOCKINGCOLLECTION_H
-#define TEMPBLOCKINGCOLLECTION_H
-
-#include "backend/backendcollection.h"
-
-// implement a temporary collection that blocks every call.
-class TempBlockingCollection : public BackendCollection
-{
- Q_OBJECT
-
-public:
- TempBlockingCollection(const QString &id, BackendCollectionManager *parent);
- virtual ~TempBlockingCollection();
- virtual QString id() const;
- virtual BackendReturn<QString> label() const;
- virtual BackendReturn<void> setLabel(const QString &label);
- virtual QDateTime created() const;
- virtual QDateTime modified() const;
- virtual bool isLocked() const;
- virtual BackendReturn<QList<BackendItem*> > items() const;
- virtual BackendReturn<QList<BackendItem*> > searchItems(const QMap<QString, \
QString> &attributes) const;
- virtual UnlockCollectionJob *createUnlockJob();
- virtual LockCollectionJob *createLockJob();
- virtual DeleteCollectionJob *createDeleteJob();
- virtual CreateItemJob *createCreateItemJob(const QString &label,
- const QMap<QString, QString> \
&attributes,
- const QCA::SecureArray &secret, bool \
locked,
- bool replace);
- virtual ChangeAuthenticationCollectionJob *createChangeAuthenticationJob();
-
-protected:
- BackendReturn<BackendItem*> createItem(const QString &label,
- const QMap<QString, QString> &attributes,
- const QCA::SecureArray &secret, bool \
locked,
- bool replace);
-
-private Q_SLOTS:
- void slotItemDeleted(BackendItem *item);
- void deleteCollectionJobResult(QueuedJob *job);
-
-private:
- friend class TempBlockingCreateItemJob;
-
- QString m_id;
- QString m_label;
- QDateTime m_created;
- QDateTime m_modified;
-
- QList<BackendItem*> m_items;
-};
-
-#endif
diff --git a/daemon/tests/tempblockingcollectionmanager.cpp \
b/daemon/tests/tempblockingcollectionmanager.cpp deleted file mode 100644
index 3c57fad..0000000
--- a/daemon/tests/tempblockingcollectionmanager.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "tempblockingcollectionmanager.h"
-#include "tempblockingcollection.h"
-#include "tempblockingjobs.h"
-
-#include <secrettool.h>
-
-TempBlockingCollectionManager::TempBlockingCollectionManager(QObject *parent)
- : BackendCollectionManager(parent)
-{
-}
-
-TempBlockingCollectionManager::~TempBlockingCollectionManager()
-{
-}
-
-CreateCollectionJob *TempBlockingCollectionManager::createCreateCollectionJob(const \
QString &label,
- bool \
locked)
-{
- TempBlockingCreateCollectionJob *job = new TempBlockingCreateCollectionJob(label,
- \
locked,
- this);
- connect(job, SIGNAL(result(QueuedJob*)),
- SLOT(createCollectionJobResult(QueuedJob*)));
- return job;
-}
-
-void TempBlockingCollectionManager::createCollectionJobResult(QueuedJob *job)
-{
- CreateCollectionJob *ccj = qobject_cast<CreateCollectionJob*>(job);
- Q_ASSERT(ccj);
-
- if (!ccj->collection()) {
- return;
- }
-
- // connect signals
- connect(ccj->collection(), SIGNAL(collectionDeleted(BackendCollection*)),
- SIGNAL(collectionDeleted(BackendCollection*)));
- emit collectionCreated(ccj->collection());
-}
-
-#include "tempblockingcollectionmanager.moc"
diff --git a/daemon/tests/tempblockingcollectionmanager.h \
b/daemon/tests/tempblockingcollectionmanager.h deleted file mode 100644
index 4272d29..0000000
--- a/daemon/tests/tempblockingcollectionmanager.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TEMPBLOCKINGCOLLECTIONMANAGER_H
-#define TEMPBLOCKINGCOLLECTIONMANAGER_H
-
-#include "backend/backendcollectionmanager.h"
-
-class TempBlockingCollection;
-
-// implement a temporary collection manager that blocks every call.
-class TempBlockingCollectionManager : public BackendCollectionManager
-{
- Q_OBJECT
-
-public:
- friend class TempBlockingCollection;
-
-public:
- TempBlockingCollectionManager(QObject *parent = 0);
- virtual ~TempBlockingCollectionManager();
- virtual CreateCollectionJob *createCreateCollectionJob(const QString &label,
- bool locked);
-
-private Q_SLOTS:
- void createCollectionJobResult(QueuedJob *job);
-};
-
-#endif
diff --git a/daemon/tests/tempblockingitem.cpp b/daemon/tests/tempblockingitem.cpp
deleted file mode 100644
index b819bd3..0000000
--- a/daemon/tests/tempblockingitem.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "tempblockingitem.h"
-#include "tempblockingcollection.h"
-#include "tempblockingjobs.h"
-
-TempBlockingItem::TempBlockingItem(const QString &id, TempBlockingCollection \
*parent)
- : BackendItem(parent), m_id(id)
-{
- QDateTime now = QDateTime::currentDateTime();
- m_created = now;
- m_modified = now;
-}
-
-TempBlockingItem::~TempBlockingItem()
-{
-}
-
-QString TempBlockingItem::id() const
-{
- return m_id;
-}
-
-BackendReturn<QString> TempBlockingItem::label() const
-{
- return m_label;
-}
-
-BackendReturn<void> TempBlockingItem::setLabel(const QString &label)
-{
- m_label = label;
- markAsModified();
- return BackendReturn<void>();
-}
-
-BackendReturn<QCA::SecureArray> TempBlockingItem::secret() const
-{
- return m_secret;
-}
-
-BackendReturn<void> TempBlockingItem::setSecret(const QCA::SecureArray &secret)
-{
- m_secret = secret;
- markAsModified();
- return BackendReturn<void>();
-}
-
-BackendReturn<QMap<QString, QString> > TempBlockingItem::attributes() const
-{
- return m_attributes;
-}
-
-BackendReturn<void> TempBlockingItem::setAttributes(const QMap<QString, QString> \
&attributes)
-{
- m_attributes = attributes;
- markAsModified();
- return BackendReturn<void>();
-}
-
-QDateTime TempBlockingItem::created() const
-{
- return m_created;
-}
-
-QDateTime TempBlockingItem::modified() const
-{
- return m_modified;
-}
-
-bool TempBlockingItem::isLocked() const
-{
- return false;
-}
-
-UnlockItemJob *TempBlockingItem::createUnlockJob()
-{
- return new TempBlockingUnlockItemJob(this);
-}
-
-LockItemJob *TempBlockingItem::createLockJob()
-{
- return new TempBlockingLockItemJob(this);
-}
-
-DeleteItemJob *TempBlockingItem::createDeleteJob()
-{
- TempBlockingDeleteItemJob *job = new TempBlockingDeleteItemJob(this);
- connect(job, SIGNAL(result(QueuedJob*)), SLOT(deleteItemJobResult(QueuedJob*)));
- return job;
-}
-
-ChangeAuthenticationItemJob *TempBlockingItem::createChangeAuthenticationJob()
-{
- return new TempBlockingChangeAuthenticationItemJob(this);
-}
-
-bool TempBlockingItem::matches(const QMap<QString, QString> &attributes)
-{
- QMap<QString, QString>::const_iterator it = attributes.constBegin();
- QMap<QString, QString>::const_iterator end = attributes.constEnd();
- for ( ; it != end; ++it) {
- if (!m_attributes.contains(it.key()) ||
- m_attributes.value(it.key()) != it.value()) {
- return false;
- }
- }
-
- return true;
-}
-
-void TempBlockingItem::deleteItemJobResult(QueuedJob *job)
-{
- TempBlockingDeleteItemJob *dij = qobject_cast<TempBlockingDeleteItemJob*>(job);
- Q_ASSERT(dij);
- if (!dij->result()) {
- return;
- }
- emit itemDeleted(this);
-}
-
-void TempBlockingItem::markAsModified()
-{
- m_modified = QDateTime::currentDateTime();
- emit itemChanged(this);
-}
-
-#include "tempblockingitem.moc"
diff --git a/daemon/tests/tempblockingitem.h b/daemon/tests/tempblockingitem.h
deleted file mode 100644
index 1b16a0c..0000000
--- a/daemon/tests/tempblockingitem.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TEMPBLOCKINGITEM_H
-#define TEMPBLOCKINGITEM_H
-
-#include "backend/backenditem.h"
-
-class TempBlockingCollection;
-
-// temporary item that blocks every call
-class TempBlockingItem : public BackendItem
-{
- Q_OBJECT
-
-public:
- friend class TempBlockingCollection;
-
- TempBlockingItem(const QString &id, TempBlockingCollection *parent);
- ~TempBlockingItem();
- virtual QString id() const;
- virtual BackendReturn<QString> label() const;
- virtual BackendReturn<void> setLabel(const QString &label);
- virtual BackendReturn<QCA::SecureArray> secret() const;
- virtual BackendReturn<void> setSecret(const QCA::SecureArray &secret);
- virtual BackendReturn<QMap<QString, QString> > attributes() const;
- virtual BackendReturn<void> setAttributes(const QMap<QString, QString> \
&attributes);
- virtual QDateTime created() const;
- virtual QDateTime modified() const;
- virtual bool isLocked() const;
- virtual UnlockItemJob *createUnlockJob();
- virtual LockItemJob *createLockJob();
- virtual DeleteItemJob *createDeleteJob();
- virtual ChangeAuthenticationItemJob *createChangeAuthenticationJob();
- bool matches(const QMap<QString, QString> &attributes);
-
-private Q_SLOTS:
- void deleteItemJobResult(QueuedJob *job);
-
-private:
- void markAsModified();
-
- QString m_id;
- QString m_label;
- QDateTime m_created;
- QDateTime m_modified;
- QMap<QString, QString> m_attributes;
-
- QCA::SecureArray m_secret;
-};
-
-#endif
diff --git a/daemon/tests/tempblockingjobs.cpp b/daemon/tests/tempblockingjobs.cpp
deleted file mode 100644
index 47382e2..0000000
--- a/daemon/tests/tempblockingjobs.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "tempblockingjobs.h"
-
-#include <secrettool.h>
-
-#include <QtCore/QTimer>
-
-TempBlockingCreateCollectionJob::TempBlockingCreateCollectionJob(const QString \
&label, bool locked,
- \
TempBlockingCollectionManager *manager)
- : CreateCollectionJob(label, locked, manager)
-{
-}
-
-void TempBlockingCreateCollectionJob::perform()
-{
- TempBlockingCollection *coll = new TempBlockingCollection(createId(), manager());
- coll->setLabel(label());
-
- setCollection(coll);
- emitResult();
-}
-
-TempBlockingUnlockCollectionJob::TempBlockingUnlockCollectionJob(BackendCollection* \
coll)
- : UnlockCollectionJob(coll)
-{
-}
-
-void TempBlockingUnlockCollectionJob::perform()
-{
- setResult(true);
- emitResult();
-}
-
-TempBlockingLockCollectionJob::TempBlockingLockCollectionJob(BackendCollection* \
coll)
- : LockCollectionJob(coll)
-{
-}
-
-void TempBlockingLockCollectionJob::perform()
-{
- setError(ErrorNotSupported);
- setResult(false);
- emitResult();
-}
-
-TempBlockingDeleteCollectionJob::TempBlockingDeleteCollectionJob(BackendCollection* \
coll)
- : DeleteCollectionJob(coll)
-{
-}
-
-void TempBlockingDeleteCollectionJob::perform()
-{
- setResult(true);
- collection()->deleteLater();
- emitResult();
-}
-
-TempBlockingChangeAuthenticationCollectionJob::TempBlockingChangeAuthenticationCollectionJob(BackendCollection* \
coll)
- : ChangeAuthenticationCollectionJob(coll)
-{
-}
-
-void TempBlockingChangeAuthenticationCollectionJob::perform()
-{
- setError(ErrorNotSupported);
- setResult(false);
- emitResult();
-}
-
-TempBlockingCreateItemJob::TempBlockingCreateItemJob(const QString& label,
- const QMap< QString, QString >& \
attributes,
- const QCA::SecureArray& secret, \
bool locked,
- bool replace,
- TempBlockingCollection* \
collection)
- : CreateItemJob(label, attributes, secret, locked, replace, collection),
- m_tempColl(collection)
-{
-}
-
-void TempBlockingCreateItemJob::perform()
-{
- BackendReturn<BackendItem*> rc = m_tempColl->createItem(label(), attributes(),
- secret(), locked(),
- replace());
-
- if (rc.isError()) {
- setError(rc.error(), rc.errorMessage());
- } else {
- setItem(rc.value());
- }
- emitResult();
-}
-
-TempBlockingUnlockItemJob::TempBlockingUnlockItemJob(BackendItem* item)
- : UnlockItemJob(item)
-{
-}
-
-void TempBlockingUnlockItemJob::perform()
-{
- setResult(true);
- emitResult();
-}
-
-TempBlockingLockItemJob::TempBlockingLockItemJob(BackendItem* item)
- : LockItemJob(item)
-{
-}
-
-void TempBlockingLockItemJob::perform()
-{
- setError(ErrorNotSupported);
- setResult(false);
- emitResult();
-}
-
-TempBlockingDeleteItemJob::TempBlockingDeleteItemJob(BackendItem* item)
- : DeleteItemJob(item)
-{
-}
-
-void TempBlockingDeleteItemJob::perform()
-{
- setResult(true);
- item()->deleteLater();
- emitResult();
-}
-
-TempBlockingChangeAuthenticationItemJob::TempBlockingChangeAuthenticationItemJob(BackendItem* \
item)
- : ChangeAuthenticationItemJob(item)
-{
-}
-
-void TempBlockingChangeAuthenticationItemJob::perform()
-{
- setError(ErrorNotSupported);
- setResult(false);
- emitResult();
-}
-
-#include "tempblockingjobs.moc"
diff --git a/daemon/tests/tempblockingjobs.h b/daemon/tests/tempblockingjobs.h
deleted file mode 100644
index bf04014..0000000
--- a/daemon/tests/tempblockingjobs.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) version 3 or any later version
- * accepted by the membership of KDE e.V. (or its successor approved
- * by the membership of KDE e.V.), which shall act as a proxy
- * defined in Section 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TEMPBLOCKINGJOBS_H
-#define TEMPBLOCKINGJOBS_H
-
-#include "tempblockingcollectionmanager.h"
-#include "tempblockingcollection.h"
-#include "tempblockingitem.h"
-
-#include <QtCore/QTimer>
-
-class TempBlockingCreateCollectionJob : public CreateCollectionJob
-{
- Q_OBJECT
-
-public:
- TempBlockingCreateCollectionJob(const QString &label, bool locked,
- TempBlockingCollectionManager *manager);
- virtual bool isImmediate() const { return false; }
- virtual void exec() { Q_ASSERT(false); }
- virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
- void perform();
-};
-
-class TempBlockingUnlockCollectionJob : public UnlockCollectionJob
-{
- Q_OBJECT
-
-public:
- TempBlockingUnlockCollectionJob(BackendCollection *coll);
- virtual bool isImmediate() const { return false; }
- virtual void exec() { Q_ASSERT(false); }
- virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
- void perform();
-};
-
-class TempBlockingDeleteCollectionJob : public DeleteCollectionJob
-{
- Q_OBJECT
-
-public:
- TempBlockingDeleteCollectionJob(BackendCollection *coll);
- virtual bool isImmediate() const { return false; }
- virtual void exec() { Q_ASSERT(false); }
- virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
- void perform();
-};
-
-class TempBlockingLockCollectionJob : public LockCollectionJob
-{
- Q_OBJECT
-
-public:
- TempBlockingLockCollectionJob(BackendCollection *coll);
- virtual bool isImmediate() const { return false; }
- virtual void exec() { Q_ASSERT(false); }
- virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
- void perform();
-};
-
-class TempBlockingChangeAuthenticationCollectionJob : public \
ChangeAuthenticationCollectionJob
-{
- Q_OBJECT
-
-public:
- TempBlockingChangeAuthenticationCollectionJob(BackendCollection *coll);
- virtual bool isImmediate() const { return false; }
- virtual void exec() { Q_ASSERT(false); }
- virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
- void perform();
-};
-
-class TempBlockingCreateItemJob : public CreateItemJob
-{
- Q_OBJECT
-
-public:
- TempBlockingCreateItemJob(const QString &label, const QMap<QString, QString> \
&attributes,
- const QCA::SecureArray &secret, bool locked, bool \
replace,
- TempBlockingCollection *collection);
- virtual bool isImmediate() const { return false; }
- virtual void exec() { Q_ASSERT(false); }
- virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
- void perform();
-
-private:
- TempBlockingCollection* m_tempColl;
-};
-
-class TempBlockingUnlockItemJob : public UnlockItemJob
-{
- Q_OBJECT
-
-public:
- TempBlockingUnlockItemJob(BackendItem *item);
- virtual bool isImmediate() const { return false; }
- virtual void exec() { Q_ASSERT(false); }
- virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
- void perform();
-};
-
-class TempBlockingLockItemJob : public LockItemJob
-{
- Q_OBJECT
-
-public:
- TempBlockingLockItemJob(BackendItem *item);
- virtual bool isImmediate() const { return false; }
- virtual void exec() { Q_ASSERT(false); }
- virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
- void perform();
-};
-
-class TempBlockingDeleteItemJob : public DeleteItemJob
-{
- Q_OBJECT
-
-public:
- TempBlockingDeleteItemJob(BackendItem *item);
- virtual bool isImmediate() const { return false; }
- virtual void exec() { Q_ASSERT(false); }
- virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
- void perform();
-};
-
-class TempBlockingChangeAuthenticationItemJob : public ChangeAuthenticationItemJob
-{
- Q_OBJECT
-
-public:
- TempBlockingChangeAuthenticationItemJob(BackendItem *item);
- virtual bool isImmediate() const { return false; }
- virtual void exec() { Q_ASSERT(false); }
- virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
- void perform();
-};
-
-#endif
diff --git a/frontend/CMakeLists.txt b/frontend/CMakeLists.txt
new file mode 100644
index 0000000..e7329dc
--- /dev/null
+++ b/frontend/CMakeLists.txt
@@ -0,0 +1,22 @@
+INCLUDE_DIRECTORIES (${CMAKE_CURRENT_SOURCE_DIR})
+ADD_SUBDIRECTORY (tests)
+
+SET (ksecretservice_frontend_SRCS
+ # fd.o Secret Storage daemon
+ secret/item.cpp
+ secret/collection.cpp
+ secret/prompt.cpp
+ secret/secret.cpp
+ secret/service.cpp
+ secret/session.cpp
+ # Daemon DBus adaptors
+ secret/adaptors/dbustypes.cpp
+ secret/adaptors/collectionadaptor.cpp
+ secret/adaptors/itemadaptor.cpp
+ secret/adaptors/promptadaptor.cpp
+ secret/adaptors/serviceadaptor.cpp
+ secret/adaptors/sessionadaptor.cpp
+)
+
+KDE4_ADD_LIBRARY (ksecretservicefrontend STATIC ${ksecretservice_frontend_SRCS})
+TARGET_LINK_LIBRARIES (ksecretservicefrontend ${KDE4_KDECORE_LIBS} \
${QCA2_LIBRARIES})
diff --git a/frontend/secret/adaptors/collectionadaptor.cpp \
b/frontend/secret/adaptors/collectionadaptor.cpp new file mode 100644
index 0000000..35b431a
--- /dev/null
+++ b/frontend/secret/adaptors/collectionadaptor.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "collectionadaptor.h"
+#include "../collection.h"
+
+namespace orgFreedesktopSecret
+{
+
+CollectionAdaptor::CollectionAdaptor(Collection *collection)
+ : QDBusAbstractAdaptor(collection), m_collection(collection)
+{
+ Q_ASSERT(collection);
+
+ connect(m_collection, SIGNAL(itemCreated(const QDBusObjectPath &)),
+ SIGNAL(ItemCreated(const QDBusObjectPath &)));
+ connect(m_collection, SIGNAL(itemDeleted(const QDBusObjectPath &)),
+ SIGNAL(ItemDeleted(const QDBusObjectPath &)));
+ connect(m_collection, SIGNAL(itemChanged(const QDBusObjectPath &)),
+ SIGNAL(ItemChanged(const QDBusObjectPath &)));
+}
+
+const QList<QDBusObjectPath> &CollectionAdaptor::items() const
+{
+ return m_collection->items();
+}
+
+void CollectionAdaptor::setLabel(const QString &label)
+{
+ m_collection->setLabel(label);
+}
+
+QString CollectionAdaptor::label() const
+{
+ return m_collection->label();
+}
+
+bool CollectionAdaptor::locked() const
+{
+ return m_collection->locked();
+}
+
+qulonglong CollectionAdaptor::created() const
+{
+ return m_collection->created();
+}
+
+qulonglong CollectionAdaptor::modified() const
+{
+ return m_collection->modified();
+}
+
+QDBusObjectPath CollectionAdaptor::Delete()
+{
+ return m_collection->deleteCollection();
+}
+
+QList<QDBusObjectPath> CollectionAdaptor::SearchItems(const StringStringMap \
&attributes) +{
+ return m_collection->searchItems(attributes);
+}
+
+QDBusObjectPath CollectionAdaptor::CreateItem(const QMap<QString, QVariant> \
&properties, + const Secret &secret, \
bool replace, + QDBusObjectPath &prompt)
+{
+ return m_collection->createItem(properties, secret, replace, prompt);
+}
+
+}
+
+#include "collectionadaptor.moc"
diff --git a/frontend/secret/adaptors/collectionadaptor.h \
b/frontend/secret/adaptors/collectionadaptor.h new file mode 100644
index 0000000..cb7ad00
--- /dev/null
+++ b/frontend/secret/adaptors/collectionadaptor.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ORG_FREEDESKTOP_SECRET_COLLECTIONADAPTOR_H
+#define ORG_FREEDESKTOP_SECRET_COLLECTIONADAPTOR_H
+
+#include "dbustypes.h"
+
+#include <QtDBus/QDBusAbstractAdaptor>
+
+class Collection;
+
+namespace orgFreedesktopSecret
+{
+
+/**
+ * D-Bus adaptor class for Collection objects.
+ */
+class CollectionAdaptor : public QDBusAbstractAdaptor
+{
+ Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Collection")
+ Q_PROPERTY(QList<QDBusObjectPath> Items READ items)
+ Q_PROPERTY(QString Label READ label WRITE setLabel)
+ Q_PROPERTY(bool Locked READ locked)
+ Q_PROPERTY(qulonglong Created READ created)
+ Q_PROPERTY(qulonglong Modified READ modified)
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param collection collection object to attach the adaptor to
+ */
+ CollectionAdaptor(Collection *collection);
+
+ const QList<QDBusObjectPath> &items() const;
+
+ void setLabel(const QString &label);
+
+ QString label() const;
+
+ bool locked() const;
+
+ qulonglong created() const;
+
+ qulonglong modified() const;
+
+public Q_SLOTS:
+ QDBusObjectPath Delete();
+
+ QList<QDBusObjectPath> SearchItems(const StringStringMap &attributes);
+
+ QDBusObjectPath CreateItem(const QMap<QString, QVariant> &properties,
+ const Secret &secret, bool replace,
+ QDBusObjectPath &prompt);
+
+Q_SIGNALS:
+ void ItemCreated(const QDBusObjectPath &item);
+
+ void ItemDeleted(const QDBusObjectPath &item);
+
+ void ItemChanged(const QDBusObjectPath &item);
+
+private:
+ Collection *m_collection;
+};
+
+}
+
+#endif
diff --git a/frontend/secret/adaptors/dbustypes.cpp \
b/frontend/secret/adaptors/dbustypes.cpp new file mode 100644
index 0000000..6d5362f
--- /dev/null
+++ b/frontend/secret/adaptors/dbustypes.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dbustypes.h"
+
+#include <QtDBus/QDBusMetaType>
+
+void registerDBusTypes()
+{
+ // register meta-types needed for this adaptor
+ qRegisterMetaType<Secret>();
+ qDBusRegisterMetaType<Secret>();
+ qRegisterMetaType<StringStringMap>();
+ qDBusRegisterMetaType<StringStringMap>();
+ qDBusRegisterMetaType<ObjectPathSecretMap>();
+}
diff --git a/frontend/secret/adaptors/dbustypes.h \
b/frontend/secret/adaptors/dbustypes.h new file mode 100644
index 0000000..12425dc
--- /dev/null
+++ b/frontend/secret/adaptors/dbustypes.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ORG_FREEDESKTOP_SECRET_DBUSTYPES_H
+#define ORG_FREEDESKTOP_SECRET_DBUSTYPES_H
+
+#include "../secret.h"
+
+#include <QtDBus/QDBusObjectPath>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+
+/**
+ * Register the types needed for the fd.o Secrets D-Bus interface.
+ */
+void registerDBusTypes();
+
+typedef QMap<QString, QString> StringStringMap;
+typedef QMap<QDBusObjectPath, Secret> ObjectPathSecretMap;
+
+Q_DECLARE_METATYPE(StringStringMap);
+Q_DECLARE_METATYPE(ObjectPathSecretMap);
+
+#endif
diff --git a/frontend/secret/adaptors/itemadaptor.cpp \
b/frontend/secret/adaptors/itemadaptor.cpp new file mode 100644
index 0000000..04f68ea
--- /dev/null
+++ b/frontend/secret/adaptors/itemadaptor.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "itemadaptor.h"
+#include "../item.h"
+#include "../secret.h"
+
+namespace orgFreedesktopSecret
+{
+
+ItemAdaptor::ItemAdaptor(Item *item)
+ : QDBusAbstractAdaptor(item), m_item(item)
+{
+ Q_ASSERT(item);
+}
+
+bool ItemAdaptor::locked() const
+{
+ return m_item->locked();
+}
+
+void ItemAdaptor::setAttributes(const StringStringMap &attributes)
+{
+ m_item->setAttributes(attributes);
+}
+
+StringStringMap ItemAdaptor::attributes() const
+{
+ return m_item->attributes();
+}
+
+void ItemAdaptor::setLabel(const QString &label)
+{
+ m_item->setLabel(label);
+}
+
+QString ItemAdaptor::label() const
+{
+ return m_item->label();
+}
+
+qulonglong ItemAdaptor::created() const
+{
+ return m_item->created();
+}
+
+qulonglong ItemAdaptor::modified() const
+{
+ return m_item->modified();
+}
+
+QDBusObjectPath ItemAdaptor::Delete()
+{
+ return m_item->deleteItem();
+}
+
+Secret ItemAdaptor::GetSecret(const QDBusObjectPath &session)
+{
+ return m_item->getSecret(session);
+}
+
+void ItemAdaptor::SetSecret(const Secret &secret)
+{
+ m_item->setSecret(secret);
+}
+
+}
+
+#include "itemadaptor.moc"
diff --git a/frontend/secret/adaptors/itemadaptor.h \
b/frontend/secret/adaptors/itemadaptor.h new file mode 100644
index 0000000..2037c17
--- /dev/null
+++ b/frontend/secret/adaptors/itemadaptor.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ORG_FREEDESKTOP_SECRET_ITEMADAPTOR_H
+#define ORG_FREEDESKTOP_SECRET_ITEMADAPTOR_H
+
+#include "dbustypes.h"
+
+#include <QtDBus/QDBusAbstractAdaptor>
+#include <QtCore/QString>
+#include <QtCore/QMap>
+
+class Item;
+
+namespace orgFreedesktopSecret
+{
+
+/**
+ * D-Bus adaptor class for Item objects.
+ */
+class ItemAdaptor : public QDBusAbstractAdaptor
+{
+ Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Item")
+ Q_PROPERTY(bool Locked READ locked)
+ Q_PROPERTY(StringStringMap Attributes READ attributes WRITE setAttributes)
+ Q_PROPERTY(QString Label READ label WRITE setLabel)
+ Q_PROPERTY(qulonglong Created READ created)
+ Q_PROPERTY(qulonglong Modified READ modified)
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param item item object to attach the adaptor to
+ */
+ ItemAdaptor(Item *item);
+
+ bool locked() const;
+
+ void setAttributes(const StringStringMap &attributes);
+
+ StringStringMap attributes() const;
+
+ void setLabel(const QString &label);
+
+ QString label() const;
+
+ qulonglong created() const;
+
+ qulonglong modified() const;
+
+public Q_SLOTS:
+ QDBusObjectPath Delete();
+
+ Secret GetSecret(const QDBusObjectPath &session);
+
+ void SetSecret(const Secret &secret);
+
+private:
+ Item *m_item;
+};
+
+}
+
+#endif
diff --git a/frontend/secret/adaptors/promptadaptor.cpp \
b/frontend/secret/adaptors/promptadaptor.cpp new file mode 100644
index 0000000..44ddda3
--- /dev/null
+++ b/frontend/secret/adaptors/promptadaptor.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "promptadaptor.h"
+#include "../prompt.h"
+
+namespace orgFreedesktopSecret
+{
+
+PromptAdaptor::PromptAdaptor(PromptBase *prompt)
+ : QDBusAbstractAdaptor(prompt), m_prompt(prompt)
+{
+ Q_ASSERT(prompt);
+
+ connect(prompt, SIGNAL(completed(bool, QVariant)), SLOT(slotCompleted(bool, \
QVariant))); +}
+
+void PromptAdaptor::Prompt(const QString &windowId)
+{
+ m_prompt->prompt(windowId);
+}
+
+void PromptAdaptor::Dismiss()
+{
+ m_prompt->dismiss();
+}
+
+void PromptAdaptor::slotCompleted(bool dismissed, const QVariant &result)
+{
+ emit Completed(dismissed, QDBusVariant(result));
+}
+
+}
+
+#include "promptadaptor.moc"
diff --git a/frontend/secret/adaptors/promptadaptor.h \
b/frontend/secret/adaptors/promptadaptor.h new file mode 100644
index 0000000..8338eca
--- /dev/null
+++ b/frontend/secret/adaptors/promptadaptor.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ORG_FREEDESKTOP_SECRET_PROMPTADAPTOR_H
+#define ORG_FREEDESKTOP_SECRET_PROMPTADAPTOR_H
+
+#include "../prompt.h"
+
+#include <QtDBus/QDBusAbstractAdaptor>
+
+namespace orgFreedesktopSecret
+{
+
+/**
+ * D-Bus adaptor class for Prompt objects.
+ */
+class PromptAdaptor : public QDBusAbstractAdaptor
+{
+ Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Prompt")
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param prompt prompt object to attach the adaptor to
+ */
+ PromptAdaptor(PromptBase *prompt);
+
+public Q_SLOTS:
+ void Prompt(const QString &windowId);
+
+ void Dismiss();
+
+Q_SIGNALS:
+ void Completed(bool dismissed, QDBusVariant result);
+
+private Q_SLOTS:
+ void slotCompleted(bool dismissed, const QVariant &result);
+
+private:
+ PromptBase *m_prompt;
+};
+
+}
+
+#endif
diff --git a/frontend/secret/adaptors/serviceadaptor.cpp \
b/frontend/secret/adaptors/serviceadaptor.cpp new file mode 100644
index 0000000..276ba19
--- /dev/null
+++ b/frontend/secret/adaptors/serviceadaptor.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "serviceadaptor.h"
+#include "dbustypes.h"
+#include "../service.h"
+
+namespace orgFreedesktopSecret
+{
+
+ServiceAdaptor::ServiceAdaptor(Service *service)
+ : QDBusAbstractAdaptor(service), m_service(service)
+{
+ Q_ASSERT(service);
+
+ // register all types needed for the D-Bus interface
+ registerDBusTypes();
+
+ connect(service, SIGNAL(collectionCreated(const QDBusObjectPath&)),
+ SIGNAL(CollectionCreated(const QDBusObjectPath&)));
+ connect(service, SIGNAL(collectionDeleted(const QDBusObjectPath&)),
+ SIGNAL(CollectionDeleted(const QDBusObjectPath&)));
+ connect(service, SIGNAL(collectionChanged(const QDBusObjectPath&)),
+ SIGNAL(CollectionChanged(const QDBusObjectPath&)));
+}
+
+const QList<QDBusObjectPath> &ServiceAdaptor::collections() const
+{
+ return m_service->collections();
+}
+
+QDBusVariant ServiceAdaptor::OpenSession(const QString &algorithm, const \
QDBusVariant &input, + QDBusObjectPath \
&result) +{
+ return QDBusVariant(m_service->openSession(algorithm, input.variant(), result));
+}
+
+QDBusObjectPath ServiceAdaptor::CreateCollection(const QMap<QString, QVariant> \
&properties, + QDBusObjectPath \
&prompt) +{
+ return m_service->createCollection(properties, prompt);
+}
+
+QList<QDBusObjectPath> ServiceAdaptor::SearchItems(const StringStringMap \
&attributes, + \
QList<QDBusObjectPath> &locked) +{
+ return m_service->searchItems(attributes, locked);
+}
+
+QList<QDBusObjectPath> ServiceAdaptor::Unlock(const QList<QDBusObjectPath> &objects,
+ QDBusObjectPath &prompt)
+{
+ return m_service->unlock(objects, prompt);
+}
+
+QList<QDBusObjectPath> ServiceAdaptor::Lock(const QList<QDBusObjectPath> &objects,
+ QDBusObjectPath &prompt)
+{
+ return m_service->lock(objects, prompt);
+}
+
+ObjectPathSecretMap ServiceAdaptor::GetSecrets(const QList<QDBusObjectPath> &items,
+ const QDBusObjectPath &session)
+{
+ return m_service->getSecrets(items, session);
+}
+
+}
+
+#include "serviceadaptor.moc"
diff --git a/frontend/secret/adaptors/serviceadaptor.h \
b/frontend/secret/adaptors/serviceadaptor.h new file mode 100644
index 0000000..436a4bd
--- /dev/null
+++ b/frontend/secret/adaptors/serviceadaptor.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ORG_FREEDESKTOP_SECRET_SERVICEADAPTOR_H
+#define ORG_FREEDESKTOP_SECRET_SERVICEADAPTOR_H
+
+#include "dbustypes.h"
+#include "../secret.h"
+
+#include <QtDBus/QDBusAbstractAdaptor>
+#include <QtDBus/QDBusObjectPath>
+
+class Service;
+
+namespace orgFreedesktopSecret
+{
+
+/**
+ * D-Bus adaptor class for Service objects.
+ */
+class ServiceAdaptor : public QDBusAbstractAdaptor
+{
+ Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Service")
+ Q_PROPERTY(QList<QDBusObjectPath> Collections READ collections)
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param service service object to attach the adaptor to
+ */
+ ServiceAdaptor(Service *service);
+
+ const QList<QDBusObjectPath> &collections() const;
+
+public Q_SLOTS:
+ QDBusVariant OpenSession(const QString &algorithm, const QDBusVariant &input,
+ QDBusObjectPath &result);
+
+ QDBusObjectPath CreateCollection(const QMap<QString, QVariant> &properties,
+ QDBusObjectPath &prompt);
+
+ QList<QDBusObjectPath> SearchItems(const StringStringMap &attributes,
+ QList<QDBusObjectPath> &locked);
+
+ QList<QDBusObjectPath> Unlock(const QList<QDBusObjectPath> &objects, \
QDBusObjectPath &prompt); +
+ QList<QDBusObjectPath> Lock(const QList<QDBusObjectPath> &objects, \
QDBusObjectPath &prompt); +
+ ObjectPathSecretMap GetSecrets(const QList<QDBusObjectPath> &items,
+ const QDBusObjectPath &session);
+
+Q_SIGNALS:
+ void CollectionCreated(const QDBusObjectPath &collection);
+
+ void CollectionDeleted(const QDBusObjectPath &collection);
+
+ void CollectionChanged(const QDBusObjectPath &collection);
+
+private:
+ Service *m_service;
+};
+
+}
+
+#endif
diff --git a/frontend/secret/adaptors/sessionadaptor.cpp \
b/frontend/secret/adaptors/sessionadaptor.cpp new file mode 100644
index 0000000..e2d1e53
--- /dev/null
+++ b/frontend/secret/adaptors/sessionadaptor.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "sessionadaptor.h"
+#include "../session.h"
+
+namespace orgFreedesktopSecret
+{
+
+SessionAdaptor::SessionAdaptor(Session *session)
+ : QDBusAbstractAdaptor(session), m_session(session)
+{
+ Q_ASSERT(session);
+}
+
+void SessionAdaptor::Close()
+{
+ m_session->close();
+}
+
+}
+
+#include "sessionadaptor.moc"
diff --git a/frontend/secret/adaptors/sessionadaptor.h \
b/frontend/secret/adaptors/sessionadaptor.h new file mode 100644
index 0000000..0eb553c
--- /dev/null
+++ b/frontend/secret/adaptors/sessionadaptor.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ORG_FREEDESKTOP_SECRET_SESSIONADAPTOR_H
+#define ORG_FREEDESKTOP_SECRET_SESSIONADAPTOR_H
+
+#include <QtDBus/QDBusAbstractAdaptor>
+
+class Session;
+
+namespace orgFreedesktopSecret
+{
+
+/**
+ * D-Bus adaptor class for Session objects.
+ */
+class SessionAdaptor : public QDBusAbstractAdaptor
+{
+ Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Session")
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param session session object to attach the adaptor to
+ */
+ SessionAdaptor(Session *session);
+
+public Q_SLOTS:
+ void Close();
+
+private:
+ Session *m_session;
+};
+
+}
+
+#endif
diff --git a/frontend/secret/collection.cpp b/frontend/secret/collection.cpp
new file mode 100644
index 0000000..e8834d2
--- /dev/null
+++ b/frontend/secret/collection.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "collection.h"
+#include "adaptors/collectionadaptor.h"
+#include "service.h"
+#include "item.h"
+#include "session.h"
+#include "prompt.h"
+
+#include <backend/backendcollection.h>
+#include <backend/backenditem.h>
+
+#include <QtDBus/QDBusConnection>
+
+#include <QtCore/QDebug>
+
+Collection::Collection(BackendCollection *collection, Service *service)
+ : QObject(service), m_service(service), m_collection(collection)
+{
+ Q_ASSERT(collection);
+ m_objectPath.setPath(service->objectPath().path() + "/collection/" + \
collection->id()); +
+ new orgFreedesktopSecret::CollectionAdaptor(this);
+ QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
+
+ connect(collection, SIGNAL(itemCreated(BackendItem*)),
+ SLOT(slotItemCreated(BackendItem*)));
+ connect(collection, SIGNAL(itemDeleted(BackendItem*)),
+ SLOT(slotItemDeleted(BackendItem*)));
+ connect(collection, SIGNAL(itemChanged(BackendItem*)),
+ SLOT(slotItemChanged(BackendItem*)));
+}
+
+const QDBusObjectPath &Collection::objectPath() const
+{
+ return m_objectPath;
+}
+
+const QList<QDBusObjectPath> &Collection::items() const
+{
+ return m_items;
+}
+
+void Collection::setLabel(const QString &label)
+{
+ BackendReturn<void> rc = m_collection->setLabel(label);
+ if (rc.isError()) {
+ // TODO: generate D-Bus error
+ }
+}
+
+QString Collection::label() const
+{
+ BackendReturn<QString> rc = m_collection->label();
+ if (rc.isError()) {
+ // TODO: generate D-Bus error
+ }
+ return rc.value();
+}
+
+bool Collection::locked() const
+{
+ return m_collection->isLocked();
+}
+
+qulonglong Collection::created() const
+{
+ return m_collection->created().toTime_t();
+}
+
+qulonglong Collection::modified() const
+{
+ return m_collection->modified().toTime_t();
+}
+
+QDBusObjectPath Collection::deleteCollection()
+{
+ DeleteCollectionJob *dcj = m_collection->createDeleteJob();
+ if (dcj->isImmediate()) {
+ dcj->exec();
+ return QDBusObjectPath("/");
+ } else {
+ SingleJobPrompt *p = new SingleJobPrompt(m_service, dcj, this);
+ return p->objectPath();
+ }
+}
+
+QList<QDBusObjectPath> Collection::searchItems(const QMap<QString, QString> \
&attributes) +{
+ QList<QDBusObjectPath> rc;
+ BackendReturn<QList<BackendItem*> > br = m_collection->searchItems(attributes);
+ if (br.isError()) {
+ // TODO: generate D-Bus error
+ }
+ else {
+ Q_FOREACH(BackendItem *item, br.value()) {
+ rc.append(QDBusObjectPath(m_objectPath.path() + "/" + item->id()));
+ }
+ }
+ return rc;
+}
+
+QDBusObjectPath Collection::createItem(const QMap<QString, QVariant> &properties,
+ const Secret &secret, bool replace,
+ QDBusObjectPath &prompt)
+{
+ // default label?
+ QString label;
+ QMap<QString, QString> attributes;
+ bool locked = false;
+
+ // get the session object
+ QObject *object = \
QDBusConnection::sessionBus().objectRegisteredAt(secret.session().path()); + \
Session *session; + if (!(session = qobject_cast<Session*>(object))) {
+ // TODO: error, requires session
+ }
+
+ if (properties.contains("Label")) {
+ label = properties["Label"].toString();
+ }
+ if (properties.contains("Locked")) {
+ locked = properties["Locked"].toBool();
+ }
+ if (properties.contains("Attributes")) {
+ attributes = qdbus_cast<StringStringMap>(properties["Attributes"].value<QDBusArgument>());
+ }
+
+ // TODO: check the parameters before creating the prompt
+ bool ok;
+ QCA::SecureArray secretValue = session->decrypt(secret, ok);
+ if (!ok) {
+ // TODO: invalid session
+ }
+ CreateItemJob *cij = m_collection->createCreateItemJob(label, attributes, \
secretValue, + replace, \
locked); + if (cij->isImmediate()) {
+ cij->exec();
+ if (cij->error() != NoError || !cij->item()) {
+ // TODO: error creating the item
+ }
+
+ // the Item is already created inside slotItemCreated()
+ prompt.setPath("/");
+ QDBusObjectPath itemPath(m_objectPath.path() + "/" + cij->item()->id());
+ return itemPath;
+ } else {
+ SingleJobPrompt *p = new SingleJobPrompt(m_service, cij, this);
+ prompt = p->objectPath();
+ return QDBusObjectPath("/");
+ }
+}
+
+BackendCollection *Collection::backendCollection() const
+{
+ return m_collection;
+}
+
+void Collection::slotItemCreated(BackendItem *item)
+{
+ Q_ASSERT(item);
+ Item *itm = new Item(item, this);
+ m_items.append(itm->objectPath());
+ emit itemCreated(itm->objectPath());
+}
+
+void Collection::slotItemDeleted(BackendItem *item)
+{
+ Q_ASSERT(item);
+ QDBusObjectPath itmPath(m_objectPath.path() + "/" + item->id());
+ m_items.removeAll(itmPath);
+ emit itemDeleted(itmPath);
+}
+
+void Collection::slotItemChanged(BackendItem *item)
+{
+ Q_ASSERT(item);
+ QDBusObjectPath itmPath(m_objectPath.path() + "/" + item->id());
+ emit itemChanged(itmPath);
+}
+
+#include "collection.moc"
diff --git a/frontend/secret/collection.h b/frontend/secret/collection.h
new file mode 100644
index 0000000..f96b414
--- /dev/null
+++ b/frontend/secret/collection.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAEMON_COLLECTION_H
+#define DAEMON_COLLECTION_H
+
+#include "secret.h"
+
+#include <QtCore/QObject>
+#include <QtDBus/QDBusObjectPath>
+
+class BackendCollection;
+class BackendItem;
+
+class Service;
+class Item;
+
+/**
+ * Represents a collection on the D-Bus implementing the \
org.freedesktop.Secret.Collection + * interface.
+ */
+class Collection : public QObject
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param collection Backend collection object
+ * @param service Parent service
+ */
+ Collection(BackendCollection *collection, Service *service);
+
+ /**
+ * Return the collection's path on the D-Bus.
+ *
+ * @return the Collection object's path
+ */
+ const QDBusObjectPath &objectPath() const;
+
+ /**
+ * Get the items stored inside this collection.
+ *
+ * @return a list of object paths of items inside the collection
+ */
+ const QList<QDBusObjectPath> &items() const;
+
+ /**
+ * Set the collection's label.
+ *
+ * @param label label to set for the collection
+ */
+ void setLabel(const QString &label);
+
+ /**
+ * Get the collection's label.
+ *
+ * @return the collection's label
+ */
+ QString label() const;
+
+ /**
+ * Check whether this collection is locked.
+ *
+ * @return true if the collection is locked, false if it is unlocked
+ */
+ bool locked() const;
+
+ /**
+ * Get the collection's creation time as a unix timestamp.
+ *
+ * @return collection's creation time
+ */
+ qulonglong created() const;
+
+ /**
+ * Get the collection's last modification time as a unix timestamp.
+ *
+ * @return collection's modification time
+ */
+ qulonglong modified() const;
+
+ /**
+ * Delete this collection.
+ *
+ * @return the object path of a Prompt object or special value "/" if the
+ * collection was deleted without prompting
+ */
+ QDBusObjectPath deleteCollection();
+
+ /**
+ * Search items inside the collection.
+ *
+ * @param attributes search attributes to match items against
+ */
+ QList<QDBusObjectPath> searchItems(const QMap<QString, QString> &attributes);
+
+ /**
+ * Create a new item inside the collection.
+ *
+ * @param properties Properties for the new item
+ * @param secret Secret for the new item
+ * @param replace if true, an existing item with the same attributes will be \
replaced, + * if false and an item with the same attributes exists, \
no new item + * will be created
+ * @param prompt object path of a prompt object if prompting is necessary or "/" \
if + * the action could be completed without a prompt
+ * @return object path of the new item or "/" if prompting is necessary
+ */
+ QDBusObjectPath createItem(const QMap<QString, QVariant> &properties,
+ const Secret &secret, bool replace, QDBusObjectPath \
&prompt); +
+ /**
+ * Get the backend collection linked to this object.
+ */
+ BackendCollection *backendCollection() const;
+
+Q_SIGNALS:
+ /**
+ * Signals the creation of a new item.
+ *
+ * @param item object path of the item that was created
+ */
+ void itemCreated(const QDBusObjectPath &item);
+
+ /**
+ * Signals the deletion of an item.
+ *
+ * @param item object path of the item that was deleted
+ */
+ void itemDeleted(const QDBusObjectPath &item);
+
+ /**
+ * Signals that an item inside the collection was changed.
+ *
+ * @param item object path of the item that was changed
+ */
+ void itemChanged(const QDBusObjectPath &item);
+
+private Q_SLOTS:
+ // handle itemCreated() calls from a backend collection
+ void slotItemCreated(BackendItem *item);
+ // handle itemDeleted() calls from a backend collection
+ void slotItemDeleted(BackendItem *item);
+ // handle itemChanged() calls from a backend collection
+ void slotItemChanged(BackendItem *item);
+
+private:
+ Service *m_service; // parent service
+ BackendCollection *m_collection;
+ QDBusObjectPath m_objectPath;
+ QList<QDBusObjectPath> m_items; // cache for items' object paths
+};
+
+#endif
diff --git a/frontend/secret/item.cpp b/frontend/secret/item.cpp
new file mode 100644
index 0000000..1d09476
--- /dev/null
+++ b/frontend/secret/item.cpp
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "item.h"
+#include "collection.h"
+#include "adaptors/itemadaptor.h"
+#include "session.h"
+#include "secret.h"
+#include "prompt.h"
+
+#include <backend/backenditem.h>
+
+#include <QtDBus/QDBusConnection>
+
+Item::Item(BackendItem *item, Collection *collection)
+ : QObject(collection), m_item(item)
+{
+ Q_ASSERT(item);
+ m_objectPath.setPath(collection->objectPath().path() + "/" + item->id());
+
+ new orgFreedesktopSecret::ItemAdaptor(this);
+ QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
+}
+
+const QDBusObjectPath &Item::objectPath() const
+{
+ return m_objectPath;
+}
+
+bool Item::locked() const
+{
+ return m_item->isLocked();
+}
+
+void Item::setAttributes(const QMap<QString, QString> &attributes)
+{
+ BackendReturn<void> rc = m_item->setAttributes(attributes);
+ if (rc.isError()) {
+ // TODO: set D-Bus error
+ }
+}
+
+QMap<QString, QString> Item::attributes() const
+{
+ BackendReturn<QMap<QString, QString> > rc = m_item->attributes();
+ if (rc.isError()) {
+ // TODO: set D-Bus error
+ }
+ return rc.value();
+}
+
+void Item::setLabel(const QString &label)
+{
+ BackendReturn<void> rc = m_item->setLabel(label);
+ if (rc.isError()) {
+ // TODO: set D-Bus error
+ }
+}
+
+QString Item::label() const
+{
+ BackendReturn<QString> rc = m_item->label();
+ if (rc.isError()) {
+ // TODO: set D-Bus error
+ }
+ return rc.value();
+}
+
+qulonglong Item::created() const
+{
+ return m_item->created().toTime_t();
+}
+
+qulonglong Item::modified() const
+{
+ return m_item->modified().toTime_t();
+}
+
+QDBusObjectPath Item::deleteItem()
+{
+ DeleteItemJob *dij = m_item->createDeleteJob();
+ if (dij->isImmediate()) {
+ dij->exec();
+ return QDBusObjectPath("/");
+ } else {
+ // FIXME: needs the service!
+ SingleJobPrompt *p = new SingleJobPrompt(0, dij, this);
+ return p->objectPath();
+ }
+}
+
+Secret Item::getSecret(const QDBusObjectPath &session)
+{
+ if (m_item->isLocked()) {
+ // TODO: error, requires unlocking
+ return Secret();
+ }
+
+ QObject *object = \
QDBusConnection::sessionBus().objectRegisteredAt(session.path()); + Session \
*sessionObj; + if (object && (sessionObj = qobject_cast<Session*>(object))) {
+ BackendReturn<QCA::SecureArray> br = m_item->secret();
+ if (br.isError()) {
+ // TODO: handle error
+ return Secret();
+ }
+ bool ok;
+ Secret secret = sessionObj->encrypt(br.value(), ok);
+ if (br.isError()) {
+ // TODO: error, invalid session
+ return Secret();
+ }
+ return secret;
+ } else {
+ // TODO: error, requires session
+ return Secret();
+ }
+}
+
+void Item::setSecret(const Secret &secret)
+{
+ if (m_item->isLocked()) {
+ // TODO: error, requires unlocking
+ return;
+ }
+
+ QObject *object = \
QDBusConnection::sessionBus().objectRegisteredAt(secret.session().path()); + \
Session *sessionObj; + if (object && (sessionObj = qobject_cast<Session*>(object))) \
{ + bool ok;
+ BackendReturn<QCA::SecureArray> br = sessionObj->decrypt(secret, ok);
+ if (!ok) {
+ // TODO: invalid session
+ return;
+ }
+ BackendReturn<void> rc = m_item->setSecret(br.value());
+ if (rc.isError()) {
+ // TODO: handle error
+ return;
+ }
+ }
+
+ // TODO: error, invalid session
+
+ return;
+}
+
+BackendItem *Item::backendItem() const
+{
+ return m_item;
+}
+
+#include "item.moc"
diff --git a/frontend/secret/item.h b/frontend/secret/item.h
new file mode 100644
index 0000000..b53df41
--- /dev/null
+++ b/frontend/secret/item.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAEMON_ITEM_H
+#define DAEMON_ITEM_H
+
+#include "secret.h"
+
+#include <QtCore/QObject>
+#include <QtDBus/QDBusContext>
+
+class BackendItem;
+class Collection;
+class Service;
+
+/**
+ * Represents an item on the D-Bus implementing the org.freedesktop.Secret.Item
+ * interface.
+ */
+class Item : public QObject, protected QDBusContext
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param item Backend item object
+ * @param collection Parent collection
+ */
+ Item(BackendItem *item, Collection *collection);
+
+ /**
+ * Return the item's path on the D-Bus.
+ *
+ * @return the Item object's path
+ */
+ const QDBusObjectPath &objectPath() const;
+
+public: // called by D-Bus adaptors
+
+ /**
+ * Check whether this item is locked.
+ *
+ * @return true if the item is locked, false if it is unlocked
+ */
+ bool locked() const;
+
+ /**
+ * Set the item's attributes.
+ *
+ * @param attributes the attributes to set for the item
+ */
+ void setAttributes(const QMap<QString, QString> &attributes);
+
+ /**
+ * Get the item's attributes.
+ *
+ * @return the attributes stored for this item
+ */
+ QMap<QString, QString> attributes() const;
+
+ /**
+ * Set the item's human-readable label.
+ *
+ * @param label label to assign to this item
+ */
+ void setLabel(const QString &label);
+
+ /**
+ * Get the human-readable label assigned to this item.
+ *
+ * @return the item assigned to this item
+ */
+ QString label() const;
+
+ /**
+ * Retrieve the item's time of creation as a unix timestamp.
+ *
+ * @return item's time of creation
+ */
+ qulonglong created() const;
+
+ /**
+ * Retrieve the item's last modification date as a unix timestamp.
+ *
+ * @return item's last time of modification
+ */
+ qulonglong modified() const;
+
+ /**
+ * Delete the item from the collection it's in.
+ *
+ * @return the object path of a prompt object for the operation or "/" if the
+ * item was deleted without a prompt.
+ */
+ QDBusObjectPath deleteItem();
+
+ /**
+ * Get the secret stored withing the item.
+ *
+ * @param session Session to use for securing the D-Bus transport
+ * @return the (possibly encrypted) Secret structure
+ */
+ Secret getSecret(const QDBusObjectPath &session);
+
+ /**
+ * Set the secret stored within the item.
+ *
+ * @param secret Secret to store inside the item
+ */
+ void setSecret(const Secret &secret);
+
+public:
+ /**
+ * Get the backend item associated with this frontend item.
+ *
+ * @return the backend item belonging to this frontend item
+ * @remarks called by other frontend objects
+ */
+ BackendItem *backendItem() const;
+
+private:
+ BackendItem *m_item;
+ QDBusObjectPath m_objectPath;
+};
+
+#endif
diff --git a/frontend/secret/prompt.cpp b/frontend/secret/prompt.cpp
new file mode 100644
index 0000000..66c1b76
--- /dev/null
+++ b/frontend/secret/prompt.cpp
@@ -0,0 +1,313 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "prompt.h"
+#include "service.h"
+#include "adaptors/promptadaptor.h"
+
+#include <backend/backendcollection.h>
+#include <backend/backenditem.h>
+#include <secrettool.h>
+
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusObjectPath>
+
+PromptBase::PromptBase(Service *service, QObject *parent)
+ : QObject(parent), m_serviceObjectPath(service->objectPath())
+{
+ Q_ASSERT(service);
+ m_objectPath.setPath(service->objectPath().path() + "/prompts/" + createId());
+
+ new orgFreedesktopSecret::PromptAdaptor(this);
+ QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
+}
+
+PromptBase::~PromptBase()
+{
+}
+
+const QDBusObjectPath &PromptBase::objectPath() const
+{
+ return m_objectPath;
+}
+
+const QDBusObjectPath &PromptBase::serviceObjectPath() const
+{
+ return m_serviceObjectPath;
+}
+
+void PromptBase::emitCompleted(bool dismissed, const QVariant &result)
+{
+ emit completed(dismissed, result);
+}
+
+SingleJobPrompt::SingleJobPrompt(Service* service, BackendJob* job, QObject* parent)
+ : PromptBase(service, parent), m_prompted(false), m_job(job)
+{
+ connect(job, SIGNAL(result(QueuedJob*)), SLOT(jobResult(QueuedJob*)));
+}
+
+SingleJobPrompt::~SingleJobPrompt()
+{
+ // TODO: delete the job?
+}
+
+void SingleJobPrompt::prompt(const QString &windowId)
+{
+ Q_UNUSED(windowId);
+ if (m_prompted) {
+ return;
+ }
+ m_prompted = true;
+
+ // TODO: convert windowId to a WId and pass it to the job
+ m_job->enqueue();
+}
+
+void SingleJobPrompt::dismiss()
+{
+ if (m_prompted) {
+ return;
+ }
+ m_prompted = true;
+
+ m_job->dismiss();
+}
+
+void SingleJobPrompt::jobResult(QueuedJob *job)
+{
+ Q_ASSERT(job == m_job);
+ // check for errors first
+ if (m_job->isDismissed()) {
+ emit completed(true, QVariant(""));
+ } else if (m_job->error() != NoError) {
+ // TODO: figure out how to handle errors gracefully.
+ emit completed(false, QVariant(""));
+ } else {
+ switch (m_job->type()) {
+
+ case BackendJob::TypeUnlockCollection:
+ case BackendJob::TypeLockCollection:
+ case BackendJob::TypeDeleteCollection:
+ case BackendJob::TypeChangeAuthenticationCollection:
+ case BackendJob::TypeDeleteItem:
+ case BackendJob::TypeLockItem:
+ case BackendJob::TypeUnlockItem:
+ case BackendJob::TypeChangeAuthenticationItem:
+ {
+ BooleanResultJob *brj = qobject_cast<BooleanResultJob*>(m_job);
+ Q_ASSERT(brj);
+ emitCompleted(false, QVariant(brj->result()));
+ }
+ break;
+
+ case BackendJob::TypeCreateCollectionMaster:
+ {
+ CreateCollectionMasterJob *ccmj = \
qobject_cast<CreateCollectionMasterJob*>(m_job); + Q_ASSERT(ccmj);
+ QDBusObjectPath result("/");
+ if (ccmj->collection()) {
+ BackendCollection *coll = ccmj->collection();
+ result.setPath(serviceObjectPath().path() + "/collection/" + \
coll->id()); + }
+
+ emitCompleted(false, qVariantFromValue(result));
+ }
+ break;
+
+ case BackendJob::TypeCreateCollection:
+ {
+ CreateCollectionJob *ccj = qobject_cast<CreateCollectionJob*>(m_job);
+ Q_ASSERT(ccj);
+ QDBusObjectPath result("/");
+ if (ccj->collection()) {
+ BackendCollection *coll = ccj->collection();
+ result.setPath(serviceObjectPath().path() + "/collection/" + \
coll->id()); + }
+
+ emitCompleted(false, qVariantFromValue(result));
+ }
+ break;
+
+ case BackendJob::TypeCreateItem:
+ {
+ CreateItemJob *cij = qobject_cast<CreateItemJob*>(m_job);
+ Q_ASSERT(cij);
+ QDBusObjectPath result("/");
+ if (cij->item()) {
+ BackendItem *item = cij->item();
+ result.setPath(serviceObjectPath().path() + "/collection/" +
+ cij->collection()->id() + "/" + item->id());
+ }
+
+ emitCompleted(false, qVariantFromValue(result));
+ }
+ break;
+
+ default:
+ // should not happen!
+ Q_ASSERT(false);
+ }
+ }
+
+ deleteLater();
+}
+
+ServiceMultiPrompt::ServiceMultiPrompt(Service *service, const QSet<BackendJob*> \
jobs, + QObject *parent)
+ : PromptBase(service, parent), m_prompted(false), m_jobs(jobs)
+{
+ bool jobTypeDetermined = false;
+ bool jobTypeUnlock = false;
+
+ Q_FOREACH(BackendJob *job, m_jobs) {
+ // make sure the subjobs are either all unlock or all lock calls
+ bool currentJobTypeUnlock = (job->type() == BackendJob::TypeUnlockCollection \
|| + job->type() == BackendJob::TypeUnlockItem);
+ if (jobTypeDetermined && jobTypeUnlock != currentJobTypeUnlock) {
+ Q_ASSERT(false);
+ } else if (!jobTypeDetermined) {
+ jobTypeUnlock = currentJobTypeUnlock;
+ jobTypeDetermined = true;
+ }
+ connect(job, SIGNAL(result(QueuedJob*)), SLOT(jobResult(QueuedJob*)));
+ }
+}
+
+ServiceMultiPrompt::~ServiceMultiPrompt()
+{
+ // TODO: delete jobs if not started?
+}
+
+void ServiceMultiPrompt::prompt(const QString &windowId)
+{
+ Q_UNUSED(windowId);
+ if (m_prompted) {
+ return;
+ }
+ m_prompted = true;
+
+ // TODO: convert windowId to a WId and pass it to the job
+ Q_FOREACH(BackendJob *job, m_jobs) {
+ job->enqueue();
+ }
+}
+
+void ServiceMultiPrompt::dismiss()
+{
+ if (m_prompted) {
+ return;
+ }
+ m_prompted = true;
+
+ Q_FOREACH(BackendJob *job, m_jobs) {
+ disconnect(job, SIGNAL(result(QueuedJob*)), this, \
SLOT(jobResult(QueuedJob*))); + job->dismiss();
+ }
+
+ // emit result right away so we don't have to catch all result() signals
+ // from individual jobs.
+ emitCompleted(true, qVariantFromValue(QList<QDBusObjectPath>()));
+ deleteLater();
+}
+
+void ServiceMultiPrompt::jobResult(QueuedJob *job)
+{
+ BackendJob *bj = qobject_cast<BackendJob*>(job);
+ Q_ASSERT(bj);
+ Q_ASSERT(m_jobs.contains(bj));
+ // remove job from the set of jobs we're waiting for
+ m_jobs.remove(bj);
+ if (bj->error() != NoError) {
+ // TODO: figure out what to do with erroneous jobs
+ } else {
+ switch (bj->type()) {
+
+ case BackendJob::TypeUnlockCollection:
+ {
+ UnlockCollectionJob *ucj = qobject_cast<UnlockCollectionJob*>(bj);
+ Q_ASSERT(ucj);
+ if (ucj->result()) {
+ BackendCollection *coll = ucj->collection();
+ QDBusObjectPath path;
+ path.setPath(serviceObjectPath().path() + "/collection/" + \
coll->id()); + m_result.append(path);
+ }
+ }
+ break;
+
+ case BackendJob::TypeLockCollection:
+ {
+ LockCollectionJob *lcj = qobject_cast<LockCollectionJob*>(bj);
+ Q_ASSERT(lcj);
+ if (lcj->result()) {
+ BackendCollection *coll = lcj->collection();
+ QDBusObjectPath path;
+ path.setPath(serviceObjectPath().path() + "/collection/" + \
coll->id()); + m_result.append(path);
+ }
+ }
+ break;
+
+ case BackendJob::TypeUnlockItem:
+ {
+ UnlockItemJob *uij = qobject_cast<UnlockItemJob*>(bj);
+ Q_ASSERT(uij);
+ if (uij->result()) {
+ BackendItem *item = uij->item();
+ BackendCollection *coll = 0;
+ // TODO: I NEED THE COLLECTION DAMMIT
+ QDBusObjectPath path;
+ path.setPath(serviceObjectPath().path() + "/collection/" + coll->id() \
+ + "/" + item->id());
+ m_result.append(path);
+ }
+ }
+ break;
+
+ case BackendJob::TypeLockItem:
+ {
+ LockItemJob *lij = qobject_cast<LockItemJob*>(bj);
+ Q_ASSERT(lij);
+ if (lij->result()) {
+ BackendItem *item = lij->item();
+ BackendCollection *coll = 0;
+ // TODO: I NEED THE COLLECTION DAMMIT
+ QDBusObjectPath path;
+ path.setPath(serviceObjectPath().path() + "/collection/" + coll->id() \
+ + "/" + item->id());
+ m_result.append(path);
+ }
+ }
+ break;
+
+ default:
+ Q_ASSERT(false);
+ }
+ }
+
+ if (m_jobs.isEmpty()) {
+ // all jobs finished
+ emitCompleted(false, qVariantFromValue(m_result));
+ deleteLater();
+ }
+}
+
+#include "prompt.moc"
diff --git a/frontend/secret/prompt.h b/frontend/secret/prompt.h
new file mode 100644
index 0000000..b5aac66
--- /dev/null
+++ b/frontend/secret/prompt.h
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAEMON_PROMPT_H
+#define DAEMON_PROMPT_H
+
+#include <backend/backendjob.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QSet>
+#include <QtDBus/QDBusObjectPath>
+#include <QtDBus/QDBusContext>
+
+class Service;
+
+/**
+ * Implementation of prompt objects according to the org.freedesktop.Secret.Prompt
+ * interface.
+ */
+class PromptBase : public QObject, protected QDBusContext
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param service Service object (used to derive the object path of the prompt)
+ * @param job the job encapsulated by the prompt
+ * @param parent Parent object
+ */
+ PromptBase(Service *service, QObject *parent);
+
+ /**
+ * Destructor.
+ */
+ virtual ~PromptBase();
+
+ /**
+ * Return the prompt's path on the D-Bus.
+ *
+ * @return the Prompt object's path
+ */
+ const QDBusObjectPath &objectPath() const;
+
+ /**
+ * Return the service object's path on the D-Bus.
+ *
+ * @return the Service object's path
+ */
+ const QDBusObjectPath &serviceObjectPath() const;
+
+ /**
+ * Perform the prompt.
+ *
+ * @param windowId Platform specific window handle to use for showing the prompt
+ * @todo implement window handle handling
+ */
+ virtual void prompt(const QString &windowId) = 0;
+
+ /**
+ * Dismiss the prompt.
+ */
+ virtual void dismiss() = 0;
+
+Q_SIGNALS:
+ /**
+ * Emitted when the operation performed by the prompt was completed
+ *
+ * @param dismissed if true the prompt was dismissed, if false it was completed
+ * @param result result of the operation encapulated by the prompt object
+ */
+ void completed(bool dismissed, QVariant result);
+
+protected:
+ /**
+ * Used to emit completed() signals in derived classes.
+ *
+ * @param dismissed if true the prompt was dismissed, if false it was completed
+ * @param result result of the operation encapsulated by the prompt object
+ */
+ void emitCompleted(bool dismissed, const QVariant &result);
+
+private:
+ QDBusObjectPath m_objectPath; // the prompt object's objectpath
+ QDBusObjectPath m_serviceObjectPath; // the service's objectpath
+};
+
+/**
+ * Prompt object encapsulating a single BackendJob.
+ */
+class SingleJobPrompt : public PromptBase
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param service Service object (used to derive the object path of the prompt)
+ * @param job the job encapsulated by the prompt
+ * @param parent Parent object
+ */
+ SingleJobPrompt(Service *service, BackendJob *job, QObject *parent = 0);
+
+ /**
+ * Destructor.
+ */
+ virtual ~SingleJobPrompt();
+
+ /**
+ * Perform the prompt.
+ *
+ * @param windowId Platform specific window handle to use for showing the prompt
+ * @todo implement window handle handling
+ */
+ virtual void prompt(const QString &windowId);
+
+ /**
+ * Dismiss the prompt.
+ */
+ virtual void dismiss();
+
+private Q_SLOTS:
+ /**
+ * Connected to the backend job's result() signal this notifies about
+ * the job's completion.
+ *
+ * @param job the job that finished
+ */
+ void jobResult(QueuedJob *job);
+
+private:
+ bool m_prompted; // true if one of the prompt()/dismiss() methods has been called \
already + BackendJob *m_job; // the encapulated job
+};
+
+/**
+ * Prompt object encapsulating a Service.Unlock or a Service.Lock call with multiple \
targets. + */
+class ServiceMultiPrompt : public PromptBase
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param service Service object (used to derive the object path of the prompt)
+ * @param jobs the unlock jobs to encapsulate
+ * @param parent parent object
+ */
+ ServiceMultiPrompt(Service *service, const QSet<BackendJob*> jobs, QObject \
*parent = 0); +
+ /**
+ * Destructor.
+ */
+ virtual ~ServiceMultiPrompt();
+
+ /**
+ * Perform the prompt.
+ *
+ * @pararm windowId Platform specific window handle to use for showing the prompt
+ * @todo implement window handling
+ */
+ virtual void prompt(const QString &windowId);
+
+ /**
+ * Dismiss this prompt.
+ */
+ virtual void dismiss();
+
+private Q_SLOTS:
+ /**
+ * Connected to the backend jobs' result() signals this notifies about a
+ * job's completion.
+ *
+ * @param job the job that finished
+ */
+ void jobResult(QueuedJob *job);
+
+private:
+ bool m_prompted; // true if one of the prompt()/dismiss() methods has been called \
already + QList<QDBusObjectPath> m_result; // resulting unlocked/locked object \
paths + QSet<BackendJob*> m_jobs; // encapsulated jobs
+};
+
+#endif
diff --git a/frontend/secret/secret.cpp b/frontend/secret/secret.cpp
new file mode 100644
index 0000000..6639f90
--- /dev/null
+++ b/frontend/secret/secret.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "secret.h"
+
+#include <QtCore/QSharedData>
+
+Secret::Secret() : d(new SecretData)
+{
+}
+
+Secret::Secret(const Secret &other) : d(other.d)
+{
+}
+
+Secret::~Secret()
+{
+}
+
+void Secret::setSession(const QDBusObjectPath &session)
+{
+ d->m_session = session;
+}
+
+const QDBusObjectPath &Secret::session() const
+{
+ return d->m_session;
+}
+
+void Secret::setParameters(const QByteArray ¶meters)
+{
+ d->m_parameters = parameters;
+}
+
+const QByteArray &Secret::parameters() const
+{
+ return d->m_parameters;
+}
+
+void Secret::setValue(const QByteArray &value)
+{
+ // TODO: encryption
+ d->m_value = value;
+}
+
+const QByteArray &Secret::value() const
+{
+ // TODO: decryption
+ return d->m_value;
+}
+
+QDBusArgument &operator<<(QDBusArgument &argument, const Secret &secret)
+{
+ argument.beginStructure();
+ argument << secret.session() << secret.parameters() << secret.value();
+ argument.endStructure();
+ return argument;
+}
+
+const QDBusArgument &operator>>(const QDBusArgument &argument, Secret &secret)
+{
+ QDBusObjectPath session;
+ QByteArray parameters;
+ QByteArray value;
+
+ argument.beginStructure();
+ argument >> session >> parameters >> value;
+ argument.endStructure();
+
+ secret.setSession(session);
+ secret.setParameters(parameters);
+ secret.setValue(value);
+
+ return argument;
+}
diff --git a/frontend/secret/secret.h b/frontend/secret/secret.h
new file mode 100644
index 0000000..8173faf
--- /dev/null
+++ b/frontend/secret/secret.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAEMON_SECRET_H
+#define DAEMON_SECRET_H
+
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QByteArray>
+#include <QtDBus/QDBusObjectPath>
+#include <QtDBus/QDBusArgument>
+#include <QtCrypto/QtCrypto>
+
+/**
+ * This class represents secret (possibly encrypted) for transfer on the
+ * D-Bus. Encryption and decryption is handled by the respective session.
+ *
+ * @remarks Objects of this class are implicitly shared
+ */
+class Secret
+{
+ // TODO: this should actually be inside secret.cpp but I'm getting strange
+ // errors if I put it there. investigate.
+ class SecretData : public QSharedData
+ {
+ public:
+ SecretData() {}
+ SecretData(const SecretData &other)
+ : QSharedData(other), m_session(other.m_session), \
m_parameters(other.m_parameters), + m_value(other.m_value) {}
+ ~SecretData() {}
+ QDBusObjectPath m_session;
+ QByteArray m_parameters;
+ QByteArray m_value;
+ };
+
+public:
+ /**
+ * Constructs an empty Secret.
+ */
+ Secret();
+
+ /**
+ * Copy constructor.
+ */
+ Secret(const Secret &other);
+
+ /**
+ * Destructor.
+ */
+ ~Secret();
+
+ /**
+ * Set the session object D-Bus path.
+ */
+ void setSession(const QDBusObjectPath &session);
+
+ /**
+ * Get the session object D-Bus path.
+ */
+ const QDBusObjectPath &session() const;
+
+ /**
+ * Set the encryption parameters.
+ */
+ void setParameters(const QByteArray ¶meters);
+
+ /**
+ * Get the encryption parameters.
+ */
+ const QByteArray ¶meters() const;
+
+ /**
+ * Set the secret's encrypted value
+ */
+ void setValue(const QByteArray &value);
+
+ /**
+ * Get the secret's encrypted value
+ */
+ const QByteArray &value() const;
+
+private:
+ class SecretData;
+ QSharedDataPointer<SecretData> d;
+};
+
+Q_DECLARE_METATYPE(Secret)
+
+QDBusArgument &operator<<(QDBusArgument &argument, const Secret &secret);
+const QDBusArgument &operator>>(const QDBusArgument &argument, Secret &secret);
+
+#endif
diff --git a/frontend/secret/service.cpp b/frontend/secret/service.cpp
new file mode 100644
index 0000000..d08ce12
--- /dev/null
+++ b/frontend/secret/service.cpp
@@ -0,0 +1,355 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "service.h"
+#include "adaptors/serviceadaptor.h"
+#include "collection.h"
+#include "prompt.h"
+#include "session.h"
+#include "secret.h"
+#include "item.h"
+
+#include <backend/backendcollection.h>
+#include <backend/backenditem.h>
+
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusMetaType>
+#include <QtDBus/QDBusMessage>
+
+Service::Service(BackendMaster *master, QObject *parent)
+ : QObject(parent), m_master(master), m_basePath("/org/freedesktop/secrets")
+{
+ Q_ASSERT(master);
+
+ new orgFreedesktopSecret::ServiceAdaptor(this);
+ QDBusConnection::sessionBus().registerObject(m_basePath.path(), this);
+
+ // TODO: make master singleton so we can get a KWallet-compatible interface
+ // on top of it as well.
+
+ connect(m_master, SIGNAL(collectionCreated(BackendCollection*)),
+ SLOT(slotCollectionCreated(BackendCollection*)));
+ connect(m_master, SIGNAL(collectionDeleted(BackendCollection*)),
+ SLOT(slotCollectionDeleted(BackendCollection*)));
+ connect(m_master, SIGNAL(collectionChanged(BackendCollection*)),
+ SLOT(slotCollectionChanged(BackendCollection*)));
+
+ // TODO: add managers to master
+}
+
+const QDBusObjectPath &Service::objectPath() const
+{
+ return m_basePath;
+}
+
+const QList<QDBusObjectPath> &Service::collections() const
+{
+ return m_collections;
+}
+
+QVariant Service::openSession(const QString &algorithm, const QVariant &input,
+ QDBusObjectPath &result)
+{
+ QVariant output;
+ QString peer;
+ if (calledFromDBus()) {
+ peer = message().service();
+ }
+ Session *session = Session::create(algorithm, input, output, peer, this);
+ if (session) {
+ result = session->objectPath();
+ } else {
+ result = QDBusObjectPath("/");
+ if (calledFromDBus()) {
+ sendErrorReply("org.freedesktop.Secret.Error.NotSupported");
+ }
+ }
+ return output;
+}
+
+QDBusObjectPath Service::createCollection(const QMap<QString, QVariant> &properties,
+ QDBusObjectPath &prompt)
+{
+ // TODO: default label
+ QString label;
+ bool locked = false;
+
+ if (properties.contains("Label")) {
+ label = properties["Label"].toString();
+ }
+ if (properties.contains("Locked")) {
+ locked = properties["Locked"].toBool();
+ }
+
+ CreateCollectionMasterJob *job = m_master->createCreateCollectionMasterJob(label, \
locked); + if (job->isImmediate()) {
+ job->exec();
+ if (job->error() != NoError || !job->collection()) {
+ // TODO: error creating the collection
+ return QDBusObjectPath("/");
+ } else {
+ BackendCollection *coll = job->collection();
+ prompt.setPath("/");
+ QDBusObjectPath collPath(m_basePath.path() + "/collection/" + coll->id());
+ return collPath;
+ }
+ } else {
+ PromptBase *p = new SingleJobPrompt(this, job, this);
+ prompt = p->objectPath();
+ return QDBusObjectPath("/");
+ }
+}
+
+QList<QDBusObjectPath> Service::searchItems(const QMap<QString, QString> \
&attributes, + QList<QDBusObjectPath> \
&locked) +{
+ // TODO: check if session exists
+ // TODO: should this rather be implemented using Daemon::Collection?
+ QList<QDBusObjectPath> unlocked;
+ Q_FOREACH(BackendCollection* collection, m_master->collections()) {
+ QString collPath = m_basePath.path() + "/collection/" + collection->id();
+ BackendReturn<QList<BackendItem*> > rc = collection->searchItems(attributes);
+ if (!rc.isError()) {
+ QList<BackendItem*> items = rc.value();
+ Q_FOREACH(BackendItem *item, items) {
+ if (item->isLocked()) {
+ locked.append(QDBusObjectPath(collPath + "/" + item->id()));
+ } else {
+ unlocked.append(QDBusObjectPath(collPath + "/" + item->id()));
+ }
+ }
+ }
+ }
+ return unlocked;
+}
+
+QList<QDBusObjectPath> Service::unlock(const QList<QDBusObjectPath> &objects,
+ QDBusObjectPath &prompt)
+{
+ // TODO: check is session exists
+ // TODO: bypass prompt
+
+ // objects already unlocked
+ QList<QDBusObjectPath> rc;
+ // jobs to call asynchronously
+ QSet<BackendJob*> unlockJobs;
+ QObject *object;
+ Item *item;
+ Collection *collection;
+ BackendItem *bi;
+ BackendCollection *bc;
+
+ Q_FOREACH(const QDBusObjectPath &path, objects) {
+ object = QDBusConnection::sessionBus().objectRegisteredAt(path.path());
+ if (!object) {
+ continue;
+ }
+ if ((collection = qobject_cast<Collection*>(object))) {
+ bc = collection->backendCollection();
+ if (bc) {
+ if (!bc->isLocked()) {
+ rc.append(path);
+ } else {
+ UnlockCollectionJob *ucj = bc->createUnlockJob();
+ if (ucj->isImmediate()) {
+ ucj->exec();
+ if (ucj->error() != NoError || !ucj->result()) {
+ // not unlocked, maybe due to an error.
+ // There's not much to do about it. Silently ignore.
+ } else {
+ rc.append(path);
+ }
+ } else {
+ unlockJobs.insert(ucj);
+ }
+ }
+ }
+ } else if ((item = qobject_cast<Item*>(object))) {
+ bi = item->backendItem();
+ if (bi) {
+ if (!bi->isLocked()) {
+ rc.append(path);
+ } else {
+ UnlockItemJob *uij = bi->createUnlockJob();
+ if (uij->isImmediate()) {
+ uij->exec();
+ if (uij->error() != NoError ||!uij->result()) {
+ // not unlocked, maybe due to an error.
+ // There's not much to do about it. Silently ignore.
+ } else {
+ rc.append(path);
+ }
+ } else {
+ unlockJobs.insert(uij);
+ }
+ }
+ }
+ }
+ // NOTE: objects which either don't exist or whose type is wrong are silently \
ignored. + }
+
+ if (!unlockJobs.isEmpty()) {
+ ServiceMultiPrompt *p = new ServiceMultiPrompt(this, unlockJobs, this);
+ prompt = p->objectPath();
+ } else {
+ prompt.setPath("/");
+ }
+
+ return rc;
+}
+
+QList<QDBusObjectPath> Service::lock(const QList<QDBusObjectPath> &objects,
+ QDBusObjectPath &prompt)
+{
+ // TODO: check is session exists
+
+ // objects already locked
+ QList<QDBusObjectPath> rc;
+ // jobs to call asynchronously
+ QSet<BackendJob*> lockJobs;
+ QObject *object;
+ Item *item;
+ Collection *collection;
+ BackendItem *bi;
+ BackendCollection *bc;
+
+ Q_FOREACH(const QDBusObjectPath &path, objects) {
+ object = QDBusConnection::sessionBus().objectRegisteredAt(path.path());
+ if (!object) {
+ continue;
+ }
+ if ((collection = qobject_cast<Collection*>(object))) {
+ bc = collection->backendCollection();
+ if (bc) {
+ if (bc->isLocked()) {
+ rc.append(path);
+ } else {
+ LockCollectionJob *lcj = bc->createLockJob();
+ if (lcj->isImmediate()) {
+ lcj->exec();
+ if (lcj->error() != NoError || !lcj->result()) {
+ // not locked, maybe due to an error.
+ // There's not much to do about it. Silently ignore.
+ } else {
+ rc.append(path);
+ }
+ } else {
+ lockJobs.insert(lcj);
+ }
+ }
+ }
+ } else if ((item = qobject_cast<Item*>(object))) {
+ bi = item->backendItem();
+ if (bi) {
+ if (bi->isLocked()) {
+ rc.append(path);
+ } else {
+ LockItemJob *lij = bi->createLockJob();
+ if (lij->isImmediate()) {
+ lij->exec();
+ if (lij->error() != NoError || !lij->result()) {
+ // not locked, maybe due to an error.
+ // There's not much to do about it. Silently ignore.
+ } else {
+ rc.append(path);
+ }
+ } else {
+ lockJobs.insert(lij);
+ }
+ }
+ }
+ }
+ // NOTE: objects which either don't exist or whose type is wrong are silently \
ignored. + }
+
+ if (!lockJobs.isEmpty()) {
+ ServiceMultiPrompt *p = new ServiceMultiPrompt(this, lockJobs, this);
+ prompt = p->objectPath();
+ } else {
+ prompt.setPath("/");
+ }
+
+ return rc;
+}
+
+QMap<QDBusObjectPath, Secret> Service::getSecrets(const QList<QDBusObjectPath> \
&items, + const QDBusObjectPath \
&session) +{
+ QMap<QDBusObjectPath, Secret> rc;
+ QObject *object;
+ Session *sessionObj;
+ Item *item;
+ bool ok;
+ Secret secret;
+
+ object = QDBusConnection::sessionBus().objectRegisteredAt(session.path());
+ if (!object || !(sessionObj = qobject_cast<Session*>(object))) {
+ if (calledFromDBus()) {
+ sendErrorReply("org.freedesktop.Secret.Error.NoSession");
+ }
+ return rc;
+ }
+
+ Q_FOREACH(const QDBusObjectPath &path, items) {
+ object = QDBusConnection::sessionBus().objectRegisteredAt(path.path());
+ if (object && (item = qobject_cast<Item*>(object))) {
+ BackendItem *bi = item->backendItem();
+ if (bi && !bi->isLocked()) {
+ BackendReturn<QCA::SecureArray> be = bi->secret();
+ // TODO: what should this do if getting the secret failed?
+ if (!be.isError()) {
+ secret = sessionObj->encrypt(be.value(), ok);
+ // TODO: what should this do if encrypting failed?
+ if (ok) {
+ rc.insert(path, secret);
+ }
+ }
+ }
+ }
+ }
+
+ return rc;
+}
+
+void Service::slotCollectionCreated(BackendCollection *collection)
+{
+ Q_ASSERT(collection);
+ Collection *coll = new Collection(collection, this);
+ m_collections.append(coll->objectPath());
+ emit collectionCreated(coll->objectPath());
+}
+
+void Service::slotCollectionDeleted(BackendCollection *collection)
+{
+ Q_ASSERT(collection);
+ QDBusObjectPath collPath(m_basePath.path() + "/collection/" + collection->id());
+ m_collections.removeAll(collPath);
+ // TODO: make sure Daemon::Collection gets destroyed
+ emit collectionDeleted(collPath);
+}
+
+void Service::slotCollectionChanged(BackendCollection *collection)
+{
+ Q_ASSERT(collection);
+ QDBusObjectPath collPath(m_basePath.path() + "/collection/" + collection->id());
+ emit collectionChanged(collPath);
+}
+
+#include "service.moc"
diff --git a/frontend/secret/service.h b/frontend/secret/service.h
new file mode 100644
index 0000000..29a8a98
--- /dev/null
+++ b/frontend/secret/service.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAEMON_SERVICE_H
+#define DAEMON_SERVICE_H
+
+#include <backend/backendmaster.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QMultiMap>
+#include <QtDBus/QDBusObjectPath>
+#include <QtDBus/QDBusContext>
+
+class Secret;
+class Collection;
+
+class _TypeRegistrar;
+
+/**
+ * Main entry point of the secret service D-Bus daemon implementing the
+ * org.freedesktop.Secret.Service interface.
+ *
+ * @todo Implement proper session handling
+ */
+class Service : public QObject, protected QDBusContext
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param master Backend master to use
+ * @param parent Parent object
+ */
+ Service(BackendMaster *master, QObject *parent = 0);
+
+ /**
+ * Return the service's path on the D-Bus.
+ *
+ * @return the Service object's path
+ */
+ const QDBusObjectPath &objectPath() const;
+
+ /**
+ * Accessor for the list of known collections.
+ *
+ * @return all collections known to the service.
+ */
+ const QList<QDBusObjectPath> &collections() const;
+
+ /**
+ * Open a unique session for the caller application.
+ *
+ * @param algorithm the algorithm the caller wishes to use
+ * @param input input arguments for the algorithm
+ * @param result the object path of the session, if session was created
+ * @return output of the session algorithm negotiation
+ */
+ QVariant openSession(const QString &algorithm, const QVariant &input, \
QDBusObjectPath &result); +
+ /**
+ * Create a new collection with the specified properties.
+ *
+ * @param properties properties for the new collection
+ * @param prompt a prompt object if prompting is necessary, or "/" if no prompt \
was needed + * @return the new collection object or "/" if prompting is necessary
+ */
+ QDBusObjectPath createCollection(const QMap<QString, QVariant> &properties,
+ QDBusObjectPath &prompt);
+
+ /**
+ * Find items in any collection.
+ *
+ * @param attributes the attributes an item has to match in order to be found
+ * @param locked items found that require authentication
+ * @return items found that are already unlocked
+ */
+ QList<QDBusObjectPath> searchItems(const QMap<QString, QString> &attributes,
+ QList<QDBusObjectPath> &locked);
+
+ /**
+ * Unlock the specified items or collections.
+ *
+ * @param objects objects to unlock
+ * @param prompt a prompt object which can be used to unlock the remaining \
objects or + * "/" if no prompt is necessary.
+ * @return objects that were unlocked without a prompt
+ */
+ QList<QDBusObjectPath> unlock(const QList<QDBusObjectPath> &objects, \
QDBusObjectPath &prompt); +
+ /**
+ * Lock the specified items or collections.
+ *
+ * @param objects objects to lock
+ * @param prompt a prompt to lock the objects or "/" if no prompt is necessary
+ * @return objects that were locked without a prompt
+ */
+ QList<QDBusObjectPath> lock(const QList<QDBusObjectPath> &objects, \
QDBusObjectPath &prompt); +
+ /**
+ * Retrieve multiple secrets from different items.
+ *
+ * @param items items to get secrets for
+ * @param session the session to use to encode the secrets
+ * @return the secrets for the items.
+ */
+ QMap<QDBusObjectPath, Secret> getSecrets(const QList<QDBusObjectPath> &items,
+ const QDBusObjectPath &session);
+
+Q_SIGNALS:
+ /**
+ * Emitted when a new collection is discovered or created.
+ *
+ * @param collection Objectpath of the collection that was discovered/created
+ */
+ void collectionCreated(const QDBusObjectPath &collection);
+
+ /**
+ * Emitted when an existing collection was deleted or disappeared.
+ *
+ * @param collection Objectpath of the collection that was deleted
+ */
+ void collectionDeleted(const QDBusObjectPath &collection);
+
+ /**
+ * Emitted when an existing collection changed.
+ *
+ * @param collection Objectpath of the collection that changed
+ */
+ void collectionChanged(const QDBusObjectPath &collection);
+
+private Q_SLOTS:
+ // handle collectionCreated() calls from master
+ void slotCollectionCreated(BackendCollection *collection);
+ // handle collectionDeleted() calls from master
+ void slotCollectionDeleted(BackendCollection *collection);
+ // handle collectionChanged() calls from master
+ void slotCollectionChanged(BackendCollection *collection);
+
+private:
+ BackendMaster *m_master;
+ QList<QDBusObjectPath> m_collections; // cache object paths of collections
+ const QDBusObjectPath m_basePath;
+};
+
+#endif
diff --git a/frontend/secret/session.cpp b/frontend/secret/session.cpp
new file mode 100644
index 0000000..704aa67
--- /dev/null
+++ b/frontend/secret/session.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "session.h"
+#include "adaptors/sessionadaptor.h"
+#include "service.h"
+
+#include <secrettool.h>
+
+#include <QtDBus/QDBusConnection>
+#include <QtCore/QRegExp>
+
+#include <QtCore/QDebug>
+
+Session::Session(Service *parent)
+ : QObject(parent),
+ m_objectPath(parent->objectPath().path() + "/session/" + createId()),
+ m_cipher(0)
+{
+ // register on the bus
+ new orgFreedesktopSecret::SessionAdaptor(this);
+ QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
+}
+
+Session::~Session()
+{
+ delete m_cipher;
+}
+
+const QDBusObjectPath &Session::objectPath() const
+{
+ return m_objectPath;
+}
+
+Session *Session::create(const QString &algorithm, const QVariant &input,
+ QVariant &output, const QString &peer, Service *parent)
+{
+ static QRegExp rxAlgorithm("^dh-ietf(\\d+)-([^-]+)-([^-]+)-([^-]+)$",
+ Qt::CaseInsensitive);
+
+ Session *session = 0;
+
+ if (algorithm == "plain") {
+ session = new Session(parent);
+ session->m_encrypted = false;
+ output.setValue(QString(""));
+ } else if (rxAlgorithm.exactMatch(algorithm) &&
+ input.type() == QVariant::ByteArray) {
+ QString encalgo = rxAlgorithm.cap(2).toLower();
+ QString blockmode = rxAlgorithm.cap(3).toLower();
+ QString padding = rxAlgorithm.cap(4).toLower();
+
+ QCA::KeyGenerator keygen;
+
+ // determine the discrete logarithm group to use
+ QCA::DLGroupSet groupnum;
+ switch (rxAlgorithm.cap(1).toInt()) {
+ case 768:
+ groupnum = QCA::IETF_768;
+ break;
+ case 1024:
+ groupnum = QCA::IETF_1024;
+ break;
+ case 1536:
+ groupnum = QCA::IETF_1536;
+ break;
+ case 2048:
+ groupnum = QCA::IETF_2048;
+ break;
+ case 3072:
+ groupnum = QCA::IETF_3072;
+ break;
+ case 4096:
+ groupnum = QCA::IETF_4096;
+ break;
+ case 6144:
+ groupnum = QCA::IETF_6144;
+ break;
+ case 8192:
+ groupnum = QCA::IETF_8192;
+ break;
+ default:
+ // no known discrete logarithm group
+ return 0;
+ }
+ QCA::DLGroup dlgroup(keygen.createDLGroup(groupnum));
+ if (dlgroup.isNull()) {
+ return 0;
+ }
+
+ // determine if we support (or want to support)
+ // the encryption algorithm.
+ if ((encalgo == "blowfish" || encalgo == "twofish" ||
+ encalgo == "aes128" || encalgo == "aes192" ||
+ encalgo == "aes256") &&
+ QCA::isSupported(QString("%1-%2-%3").arg(encalgo, blockmode, padding)
+ .toLatin1().constData())) {
+
+ // get client's public key
+ QCA::DHPublicKey clientKey(dlgroup,
+ \
QCA::BigInteger(QCA::SecureArray(input.toByteArray()))); + // generate own \
private key + QCA::PrivateKey privKey(keygen.createDH(dlgroup));
+ // generate the shared symmetric key
+ QCA::SymmetricKey sharedKey(privKey.deriveKey(clientKey));
+
+ QCA::Cipher::Mode cbm;
+ if (blockmode == "cbc") {
+ cbm = QCA::Cipher::CBC;
+ } else {
+ return 0;
+ }
+
+ QCA::Cipher::Padding cp;
+ if (padding == "pkcs7") {
+ cp = QCA::Cipher::PKCS7;
+ } else if (padding == "default") {
+ cp = QCA::Cipher::DefaultPadding;
+ } else {
+ return 0;
+ }
+
+ QCA::Cipher *cipher = new QCA::Cipher(encalgo, cbm, cp);
+
+ // check if creating the cipher worked and if our shared
+ // key is longer than the minimum length required.
+ if (sharedKey.size() >= cipher->keyLength().minimum()) {
+ // generate the response to the client so it can derive
+ // the key as well.
+ session = new Session(parent);
+ session->m_encrypted = true;
+ session->m_cipher = cipher;
+ session->m_symmetricKey = sharedKey;
+ output.setValue(privKey.toPublicKey().toDH().y().toArray().toByteArray());
+ } else {
+ return 0;
+ }
+ }
+ } else {
+ return 0;
+ }
+
+ // creating the session was successful
+ session->m_peer = peer;
+ return session;
+}
+
+Secret Session::encrypt(const QCA::SecureArray &value, bool &ok)
+{
+ ok = false;
+
+ Secret s;
+ s.setSession(m_objectPath);
+ if (m_encrypted) {
+ Q_ASSERT(m_cipher);
+ QCA::InitializationVector iv(m_cipher->blockSize());
+ m_cipher->setup(QCA::Encode, m_symmetricKey, iv);
+ QCA::SecureArray encval = m_cipher->update(value);
+ if (!m_cipher->ok()) {
+ return s;
+ }
+ encval += m_cipher->final();
+ if (m_cipher->ok()) {
+ return s;
+ }
+ s.setValue(encval.toByteArray());
+ s.setParameters(iv.toByteArray());
+ } else {
+ s.setValue(value.toByteArray());
+ }
+
+
+ ok = true;
+ return s;
+}
+
+QCA::SecureArray Session::decrypt(const Secret &secret, bool &ok)
+{
+ // make sure this is really meant for us
+ Q_ASSERT(secret.session() == m_objectPath);
+ ok = false;
+
+ QCA::SecureArray value;
+ if (m_encrypted) {
+ Q_ASSERT(m_cipher);
+ if (!secret.parameters().size() == m_cipher->blockSize()) {
+ return value;
+ }
+ QCA::InitializationVector iv(secret.parameters());
+ m_cipher->setup(QCA::Decode, m_symmetricKey, iv);
+ value = m_cipher->update(secret.value());
+ if (!m_cipher->ok()) {
+ return value;
+ }
+ value += m_cipher->final();
+ if (!m_cipher->ok()) {
+ return value;
+ }
+ } else {
+ value = secret.value();
+ }
+
+ ok = true;
+ return value;
+}
+
+void Session::close()
+{
+ deleteLater();
+}
+
+const QString &Session::peer() const
+{
+ return m_peer;
+}
+
+#include "session.moc"
diff --git a/frontend/secret/session.h b/frontend/secret/session.h
new file mode 100644
index 0000000..e2cb335
--- /dev/null
+++ b/frontend/secret/session.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAEMON_SESSION_H
+#define DAEMON_SESSION_H
+
+#include "secret.h"
+
+#include <QtCore/QObject>
+#include <QtCrypto/QtCrypto>
+
+class Service;
+
+/**
+ * Represents an open session of a client on the D-Bus implementing the
+ * org.freedesktop.Secret.Session interface.
+ *
+ * @todo stub implementation, currently only supports plain (no encryption)
+ */
+class Session : public QObject
+{
+ Q_OBJECT
+
+private:
+ /**
+ * Constructor.
+ *
+ * @param parent Parent Service object
+ */
+ Session(Service *parent);
+
+public:
+ /**
+ * Destructor.
+ */
+ ~Session();
+
+ /**
+ * Get the session's object path.
+ */
+ const QDBusObjectPath &objectPath() const;
+
+ /**
+ * Try to create a (possibly encrypted) session for the use of transferring
+ * secrets.
+ *
+ * @param algorithm the negotiation/encryption algorithm to use
+ * @param input negotiation algorithm input
+ * @param output negotiation algorithm output
+ * @param parent Parent Service object
+ * @return a session object if negotiation was successful, 0 if the algorithm \
isn't + * supported or an error occurred
+ */
+ static Session *create(const QString &algorithm, const QVariant &input,
+ QVariant &output, const QString &peer, Service *parent);
+
+ /**
+ * Encrypt a secret value using this session.
+ *
+ * @param value value to encrypt
+ * @param ok set to true if encrypting succeeds, set to false else
+ * @return the secret encrypted for transport
+ */
+ Secret encrypt(const QCA::SecureArray &value, bool &ok);
+
+ /**
+ * Decrypt a secret value using this session.
+ *
+ * @param secret Secret received on the D-Bus
+ * @param ok set to true if decrypting succeeds, set to false else
+ * @return the unencryped value
+ */
+ QCA::SecureArray decrypt(const Secret &secret, bool &ok);
+
+ /**
+ * Close this session.
+ */
+ void close();
+
+ /**
+ * Get the session's D-Bus peer (the client requesting the session).
+ */
+ const QString &peer() const;
+
+private:
+ QDBusObjectPath m_objectPath;
+ QString m_peer; // D-Bus address of the application that requested this session
+
+ // if true, use encryption, if false, use plaintext
+ bool m_encrypted;
+
+ // the cipher and the symmetric key used for encryption
+ QCA::Cipher *m_cipher;
+ QCA::SymmetricKey m_symmetricKey;
+};
+
+#endif
diff --git a/frontend/tests/CMakeLists.txt b/frontend/tests/CMakeLists.txt
new file mode 100644
index 0000000..3d8f298
--- /dev/null
+++ b/frontend/tests/CMakeLists.txt
@@ -0,0 +1,24 @@
+SET (EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
+
+INCLUDE_DIRECTORIES (
+ ${KDE4_INCLUDES}
+ ${QCA2_INCLUDE_DIR}
+ ${CMAKE_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+KDE4_ADD_EXECUTABLE (ksecretservice_frontend_test
+ servicetest.cpp
+ tempblockingcollectionmanager.cpp
+ tempblockingcollection.cpp
+ tempblockingitem.cpp
+ tempblockingjobs.cpp
+)
+TARGET_LINK_LIBRARIES (ksecretservice_frontend_test
+ ksecretservicebackend
+ ksecretservicefrontend
+ ksecretservicelib
+ ${QT_QTTEST_LIBRARIES}
+)
+
+ADD_TEST (FrontendSessionTest ksecretservice_frontend_test)
diff --git a/frontend/tests/servicetest.cpp b/frontend/tests/servicetest.cpp
new file mode 100644
index 0000000..8b76a0d
--- /dev/null
+++ b/frontend/tests/servicetest.cpp
@@ -0,0 +1,707 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "servicetest.h"
+
+#include "backend/backendmaster.h"
+#include "backend/temporary/temporarycollectionmanager.h"
+#include "tempblockingcollectionmanager.h"
+#include "secret/service.h"
+#include "secret/adaptors/dbustypes.h"
+
+#include <qtest_kde.h>
+
+#include <QtTest/QTest>
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusInterface>
+#include <QtDBus/QDBusMessage>
+#include <QtDBus/QDBusReply>
+#include <QtDBus/QDBusConnectionInterface>
+#include <QtCrypto/QtCrypto>
+
+#include <QtCore/QDebug>
+
+void ServiceTest::initTestCase()
+{
+ QVERIFY(QDBusConnection::sessionBus().registerService("org.freedesktop.Secret"));
+
+ QCA::init();
+
+ m_master = new BackendMaster;
+ m_tempCollMan = new TemporaryCollectionManager(m_master);
+ m_master->addManager(m_tempCollMan);
+ m_service = new Service(m_master);
+}
+
+void ServiceTest::dbusService()
+{
+ // make sure the service is available
+ QDBusConnectionInterface *ifaceConn = QDBusConnection::sessionBus().interface();
+ QVERIFY(ifaceConn && ifaceConn->isValid());
+
+ QDBusReply<bool> registered = \
ifaceConn->isServiceRegistered("org.freedesktop.Secret"); + \
QVERIFY(registered.isValid()); + QVERIFY(registered.value());
+}
+
+void ServiceTest::session()
+{
+ QDBusInterface ifaceService("org.freedesktop.Secret", \
"/org/freedesktop/secrets"); + QVERIFY(ifaceService.isValid());
+ QCA::KeyGenerator keygen;
+
+ // "unsupported" session algorithm
+ QList<QVariant> unsuppInput;
+ unsuppInput << QString("unsupported") << \
QVariant::fromValue(QDBusVariant(QString(""))); + QDBusMessage unsuppReply = \
ifaceService.callWithArgumentList(QDBus::Block, "OpenSession", + \
unsuppInput); + QCOMPARE(unsuppReply.type(), QDBusMessage::ErrorMessage);
+ QCOMPARE(unsuppReply.errorName(),
+ QLatin1String("org.freedesktop.Secret.Error.NotSupported"));
+
+ // "plain" session algorithm
+ QDBusObjectPath plainPath;
+ QList<QVariant> plainInput;
+ plainInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
+ QDBusMessage plainReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession", + \
plainInput); + QCOMPARE(plainReply.type(), QDBusMessage::ReplyMessage);
+ QList<QVariant> plainArgs = plainReply.arguments();
+ QCOMPARE(plainArgs.size(), 2);
+ QCOMPARE(plainArgs.at(0).userType(), qMetaTypeId<QDBusVariant>());
+ QCOMPARE(plainArgs.at(0).value<QString>(), QLatin1String(""));
+ QCOMPARE(plainArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
+ plainPath = plainArgs.at(1).value<QDBusObjectPath>();
+ QVERIFY(plainPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/session/")));
+ QDBusInterface plainIface("org.freedesktop.Secret", plainPath.path(),
+ "org.freedesktop.Secret.Session");
+ QVERIFY(plainIface.isValid());
+ QDBusMessage plainReply2 = plainIface.call("Close");
+ QCOMPARE(plainReply2.type(), QDBusMessage::ReplyMessage);
+ QCOMPARE(plainIface.call("Introspect").type(), QDBusMessage::ErrorMessage);
+
+ // "dh-ietf1024-aes128-cbc-pkcs7" encryption
+ QDBusObjectPath dhPath;
+ QList<QVariant> dhInput;
+ QCA::DLGroup dhDlgroup(keygen.createDLGroup(QCA::IETF_1024));
+ QVERIFY(!dhDlgroup.isNull());
+ QCA::PrivateKey dhPrivkey(keygen.createDH(dhDlgroup));
+ QCA::PublicKey dhPubkey(dhPrivkey);
+ QByteArray dhBytePub(dhPubkey.toDH().y().toArray().toByteArray());
+ dhInput << QString("dh-ietf1024-aes128-cbc-pkcs7")
+ << QVariant::fromValue(QDBusVariant(dhBytePub));
+ QDBusMessage dhReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession", + dhInput);
+ QCOMPARE(dhReply.type(), QDBusMessage::ReplyMessage);
+ QList<QVariant> dhArgs = dhReply.arguments();
+ QCOMPARE(dhArgs.size(), 2);
+ QCOMPARE(dhArgs.at(0).userType(), qMetaTypeId<QDBusVariant>());
+ QVariant dhOutputVar = dhArgs.at(0).value<QDBusVariant>().variant();
+ QCOMPARE(dhOutputVar.type(), QVariant::ByteArray);
+ QByteArray dhOutput = dhOutputVar.toByteArray();
+ QCA::DHPublicKey dhServiceKey(dhDlgroup,
+ QCA::BigInteger(QCA::SecureArray(dhOutput)));
+ QCA::SymmetricKey dhSharedKey(dhPrivkey.deriveKey(dhServiceKey));
+ QCA::Cipher *dhCipher = new QCA::Cipher("aes128", QCA::Cipher::CBC, \
QCA::Cipher::PKCS7); + QVERIFY(dhSharedKey.size() >= \
dhCipher->keyLength().minimum()); + QCOMPARE(plainArgs.at(1).userType(), \
qMetaTypeId<QDBusObjectPath>()); + dhPath = dhArgs.at(1).value<QDBusObjectPath>();
+ QVERIFY(dhPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/session/")));
+ QDBusInterface dhIface("org.freedesktop.Secret", dhPath.path(),
+ "org.freedesktop.Secret.Session");
+ QVERIFY(dhIface.isValid());
+ QDBusMessage dhReply2 = dhIface.call("Close");
+ QCOMPARE(dhReply2.type(), QDBusMessage::ReplyMessage);
+ QCOMPARE(dhIface.call("Introspect").type(), QDBusMessage::ErrorMessage);
+}
+
+void ServiceTest::nonBlockingCollection()
+{
+ QDBusInterface ifaceService("org.freedesktop.Secret", \
"/org/freedesktop/secrets"); + QVERIFY(ifaceService.isValid());
+
+ // create a session
+ QDBusObjectPath sessionPath;
+ QList<QVariant> sessionInput;
+ sessionInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
+ QDBusMessage sessionReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession", + \
sessionInput); + sessionPath = \
sessionReply.arguments().at(1).value<QDBusObjectPath>(); +
+ // listen to CollectionCreated/CollectionDeleted/CollectionChanged signals
+ ObjectPathSignalSpy createdSpy(&ifaceService, \
SIGNAL(CollectionCreated(QDBusObjectPath))); + QVERIFY(createdSpy.isValid());
+ ObjectPathSignalSpy deletedSpy(&ifaceService, \
SIGNAL(CollectionDeleted(QDBusObjectPath))); + QVERIFY(deletedSpy.isValid());
+ ObjectPathSignalSpy changedSpy(&ifaceService, \
SIGNAL(CollectionChanged(QDBusObjectPath))); + QVERIFY(changedSpy.isValid());
+
+ // create a collection
+ QDBusObjectPath collectionPath;
+ QMap<QString, QVariant> createProperties;
+ QList<QVariant> createInput;
+ createProperties["Label"] = "test";
+ createProperties["Locked"] = false; // create collection unlocked
+ createInput << QVariant::fromValue(createProperties);
+ QDBusMessage createReply = ifaceService.callWithArgumentList(QDBus::Block, \
"CreateCollection", + \
createInput); +
+ QCOMPARE(createReply.type(), QDBusMessage::ReplyMessage);
+ QList<QVariant> createArgs = createReply.arguments();
+ QCOMPARE(createArgs.size(), 2);
+ QCOMPARE(createArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+ QCOMPARE(createArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
+ // CreateCollection is blocking, so the first output (path) should be "/".
+ QCOMPARE(createArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
+ QDBusObjectPath promptPath = createArgs.at(1).value<QDBusObjectPath>();
+ QVERIFY(promptPath.path().startsWith(
+ QLatin1String("/org/freedesktop/secrets/prompts/")));
+
+ // prompt and wait for the result.
+ ClientPrompt *prompt = new ClientPrompt(promptPath);
+ prompt->promptAndWait(5000);
+ QVERIFY(prompt->completed());
+ QVERIFY(!prompt->dismissed());
+ QCOMPARE(prompt->result().userType(), qMetaTypeId<QDBusObjectPath>());
+ collectionPath = prompt->result().value<QDBusObjectPath>();
+ QVERIFY(collectionPath.path().startsWith(
+ QLatin1String("/org/freedesktop/secrets/collection/")));
+ QDBusInterface ifaceCollection("org.freedesktop.Secret", collectionPath.path(),
+ "org.freedesktop.Secret.Collection");
+ QVERIFY(ifaceCollection.isValid());
+ delete prompt;
+
+ // make sure the CollectionCreated signal was sent
+ if (createdSpy.size() < 1) {
+ createdSpy.waitForSignal(5000);
+ }
+ QCOMPARE(createdSpy.size(), 1);
+ QCOMPARE(createdSpy.takeFirst(), collectionPath);
+
+ // read collection properties
+ QVariant propItems = ifaceCollection.property("Items");
+ QVERIFY(propItems.isValid());
+ QVERIFY(propItems.canConvert<QList<QDBusObjectPath> >());
+ QList<QDBusObjectPath> propItemsList = propItems.value<QList<QDBusObjectPath> \
>(); + QVERIFY(propItemsList.isEmpty());
+ QVariant propLabel = ifaceCollection.property("Label");
+ QVERIFY(propLabel.isValid());
+ QCOMPARE(propLabel.type(), QVariant::String);
+ QCOMPARE(propLabel.value<QString>(), QString("test"));
+ QVariant propLocked = ifaceCollection.property("Locked");
+ QVERIFY(propLocked.isValid());
+ QCOMPARE(propLocked.value<bool>(), false);
+ QVariant propCreated = ifaceCollection.property("Created");
+ QVERIFY(propCreated.isValid());
+ QCOMPARE(propCreated.type(), QVariant::ULongLong);
+ qulonglong propCreatedUll = propCreated.value<qulonglong>();
+ QVERIFY(QDateTime::currentDateTime().toTime_t() - propCreatedUll < 60);
+ QVariant propModified = ifaceCollection.property("Modified");
+ QVERIFY(propModified.isValid());
+ QCOMPARE(propModified.type(), QVariant::ULongLong);
+ QCOMPARE(propModified.value<qulonglong>(), propCreatedUll);
+
+ // set the label and re-read it.
+ ifaceCollection.setProperty("Label", QString("test2"));
+ propLabel = ifaceCollection.property("Label");
+ QVERIFY(propLabel.isValid());
+ QCOMPARE(propLabel.type(), QVariant::String);
+ QCOMPARE(propLabel.value<QString>(), QString("test2"));
+
+ // make sure the CollectionChanged signal was sent
+ if (changedSpy.size() < 1) {
+ changedSpy.waitForSignal(5000);
+ }
+ QCOMPARE(changedSpy.size(), 1);
+ QCOMPARE(changedSpy.takeFirst(), collectionPath);
+
+ // delete the collection
+ QDBusMessage deleteReply = ifaceCollection.call(QDBus::Block, "Delete");
+ QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
+ QList<QVariant> deleteArgs = deleteReply.arguments();
+ QCOMPARE(deleteArgs.size(), 1);
+ QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+ // TemporaryCollection is non-blocking, so the output (prompt) should be "/".
+ QCOMPARE(deleteArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
+ // make sure the collection is gone
+ QCOMPARE(ifaceCollection.call("Introspect").type(), QDBusMessage::ErrorMessage);
+
+ // make sure the CollectionDeleted signal was sent
+ if (deletedSpy.size() < 1) {
+ deletedSpy.waitForSignal(5000);
+ }
+ QCOMPARE(deletedSpy.size(), 1);
+ QCOMPARE(deletedSpy.takeFirst(), collectionPath);
+
+ // close the session
+ QDBusInterface("org.freedesktop.Secret", sessionPath.path()).call("Close");
+}
+
+void ServiceTest::nonBlockingItem()
+{
+ QDBusInterface ifaceService("org.freedesktop.Secret", \
"/org/freedesktop/secrets"); +
+ // create a session
+ QDBusObjectPath sessionPath;
+ QList<QVariant> sessionInput;
+ sessionInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
+ QDBusMessage sessionReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession", + \
sessionInput); + sessionPath = \
sessionReply.arguments().at(1).value<QDBusObjectPath>(); +
+ // create a collection
+ QDBusObjectPath collectionPath;
+ QMap<QString, QVariant> collProperties;
+ QList<QVariant> collInput;
+ collProperties["Label"] = "test3";
+ collProperties["Locked"] = false;
+ collInput << QVariant::fromValue(collProperties);
+ QDBusMessage collReply = ifaceService.callWithArgumentList(QDBus::Block, \
"CreateCollection", + \
collInput); + QDBusObjectPath promptPath = \
collReply.arguments().at(1).value<QDBusObjectPath>(); + ClientPrompt *prompt = new \
ClientPrompt(promptPath); + prompt->promptAndWait(5000);
+ QVERIFY(prompt->completed());
+ collectionPath = prompt->result().value<QDBusObjectPath>();
+ delete prompt;
+ QDBusInterface ifaceColl("org.freedesktop.Secret", collectionPath.path());
+
+ ObjectPathSignalSpy createdSpy(&ifaceColl, SIGNAL(ItemCreated(QDBusObjectPath)));
+ QVERIFY(createdSpy.isValid());
+ ObjectPathSignalSpy deletedSpy(&ifaceColl, SIGNAL(ItemDeleted(QDBusObjectPath)));
+ QVERIFY(deletedSpy.isValid());
+ ObjectPathSignalSpy changedSpy(&ifaceColl, SIGNAL(ItemChanged(QDBusObjectPath)));
+ QVERIFY(changedSpy.isValid());
+
+ // create an item
+ QDBusObjectPath itemPath;
+ StringStringMap itemAttributes;
+ itemAttributes["attribute1"] = "value1";
+ itemAttributes["attribute2"] = "value2";
+ QMap<QString, QVariant> itemProperties;
+ itemProperties["Attributes"] = QVariant::fromValue(itemAttributes);
+ itemProperties["Label"] = "item1";
+ itemProperties["Locked"] = false;
+ QList<QVariant> itemInput;
+ Secret secret;
+ secret.setSession(sessionPath);
+ secret.setValue(QByteArray("mysecret"));
+ itemInput << QVariant::fromValue(itemProperties);
+ itemInput << QVariant::fromValue(secret);
+ itemInput << false;
+ QDBusMessage itemReply = ifaceColl.callWithArgumentList(QDBus::Block, \
"CreateItem", + itemInput);
+ QCOMPARE(itemReply.type(), QDBusMessage::ReplyMessage);
+ QList<QVariant> itemArgs = itemReply.arguments();
+ QCOMPARE(itemArgs.size(), 2);
+ QCOMPARE(itemArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+ QCOMPARE(itemArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
+ // TemporaryItem is non-blocking, so the second output (prompt) should be "/"
+ QCOMPARE(itemArgs.at(1).value<QDBusObjectPath>().path(), QLatin1String("/"));
+ itemPath = itemArgs.at(0).value<QDBusObjectPath>();
+ QVERIFY(itemPath.path().startsWith(collectionPath.path() + "/"));
+ QDBusInterface ifaceItem("org.freedesktop.Secret", itemPath.path(),
+ "org.freedesktop.Secret.Item");
+ QVERIFY(ifaceItem.isValid());
+
+ // make sure the ItemCreated signal was sent
+ if (createdSpy.size() < 1) {
+ createdSpy.waitForSignal(5000);
+ }
+ QCOMPARE(createdSpy.size(), 1);
+ QCOMPARE(createdSpy.takeFirst(), itemPath);
+
+ // check if the collection's Items property contains the item.
+ QVariant propItems = ifaceColl.property("Items");
+ QVERIFY(propItems.isValid());
+ QVERIFY(propItems.canConvert<QList<QDBusObjectPath> >());
+ QList<QDBusObjectPath> propItemsList = propItems.value<QList<QDBusObjectPath> \
>(); + QCOMPARE(propItemsList.count(), 1);
+ QCOMPARE(propItemsList.at(0), itemPath);
+
+ // read item properties
+ QVariant propLocked = ifaceItem.property("Locked");
+ QVERIFY(propLocked.isValid());
+ QCOMPARE(propLocked.type(), QVariant::Bool);
+ QCOMPARE(propLocked.value<bool>(), false);
+ QVariant propLabel = ifaceItem.property("Label");
+ QVERIFY(propLabel.isValid());
+ QCOMPARE(propLabel.type(), QVariant::String);
+ QCOMPARE(propLabel.value<QString>(), QLatin1String("item1"));
+ QVariant propCreated = ifaceItem.property("Created");
+ QVERIFY(propCreated.isValid());
+ QCOMPARE(propCreated.type(), QVariant::ULongLong);
+ qulonglong propCreatedUll = propCreated.value<qulonglong>();
+ QVERIFY(QDateTime::currentDateTime().toTime_t() - propCreatedUll < 60);
+ QVariant propModified = ifaceItem.property("Modified");
+ QVERIFY(propModified.isValid());
+ QCOMPARE(propModified.type(), QVariant::ULongLong);
+ QCOMPARE(propModified.value<qulonglong>(), propCreatedUll);
+ QVariant propAttributes = ifaceItem.property("Attributes");
+ QVERIFY(propAttributes.isValid());
+ QCOMPARE(propAttributes.userType(), qMetaTypeId<StringStringMap>());
+ StringStringMap propAttributesMap = propAttributes.value<StringStringMap>();
+ QCOMPARE(propAttributesMap.size(), 2);
+ QCOMPARE(propAttributesMap.value("attribute1"), QLatin1String("value1"));
+ QCOMPARE(propAttributesMap.value("attribute2"), QLatin1String("value2"));
+
+ // read the secret
+ QDBusMessage secretReply = ifaceItem.call(QDBus::Block, "GetSecret",
+ \
QVariant::fromValue<QDBusObjectPath>(sessionPath)); + QCOMPARE(secretReply.type(), \
QDBusMessage::ReplyMessage); + QList<QVariant> secretOutput = \
secretReply.arguments(); + QCOMPARE(secretOutput.count(), 1);
+ Secret outsecret = qdbus_cast<Secret>(secretOutput.at(0));
+ QCOMPARE(outsecret.session(), sessionPath);
+ QCOMPARE(outsecret.value(), QByteArray("mysecret"));
+
+ // set and re-read item properties
+ ifaceItem.setProperty("Label", QString("item2"));
+ propLabel = ifaceItem.property("Label");
+ QVERIFY(propLabel.isValid());
+ QCOMPARE(propLabel.type(), QVariant::String);
+ QCOMPARE(propLabel.value<QString>(), QLatin1String("item2"));
+ propAttributesMap["attribute3"] = "value3";
+ propAttributesMap["attribute1"] = "othervalue";
+ propAttributesMap.remove("attribute2");
+ ifaceItem.setProperty("Attributes", \
QVariant::fromValue<StringStringMap>(propAttributesMap)); + propAttributes = \
ifaceItem.property("Attributes"); + QVERIFY(propAttributes.isValid());
+ QCOMPARE(propAttributes.userType(), qMetaTypeId<StringStringMap>());
+ propAttributesMap = propAttributes.value<StringStringMap>();
+ QCOMPARE(propAttributesMap.size(), 2);
+ QCOMPARE(propAttributesMap.value("attribute1"), QLatin1String("othervalue"));
+ QCOMPARE(propAttributesMap.value("attribute3"), QLatin1String("value3"));
+
+ // set and re-read the secret
+ secret.setValue("mysecret2");
+ secretReply = ifaceItem.call(QDBus::Block, "SetSecret", \
QVariant::fromValue<Secret>(secret)); + QCOMPARE(secretReply.type(), \
QDBusMessage::ReplyMessage); + secretReply = ifaceItem.call(QDBus::Block, \
"GetSecret", + \
QVariant::fromValue<QDBusObjectPath>(sessionPath)); + QCOMPARE(secretReply.type(), \
QDBusMessage::ReplyMessage); + secretOutput = secretReply.arguments();
+ QCOMPARE(secretOutput.count(), 1);
+ outsecret = qdbus_cast<Secret>(secretOutput.at(0));
+ QCOMPARE(outsecret.session(), sessionPath);
+ QCOMPARE(outsecret.value(), QByteArray("mysecret2"));
+
+
+ // we should have received 2 ItemChanged signals
+ if (changedSpy.size() < 3) {
+ changedSpy.waitForSignals(3, 5000);
+ }
+ QCOMPARE(changedSpy.size(), 3);
+ QCOMPARE(changedSpy.takeFirst(), itemPath);
+ QCOMPARE(changedSpy.takeFirst(), itemPath);
+ QCOMPARE(changedSpy.takeFirst(), itemPath);
+
+ // delete the item
+ QDBusMessage deleteReply = ifaceItem.call(QDBus::Block, "Delete");
+ QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
+ QList<QVariant> deleteArgs = deleteReply.arguments();
+ QCOMPARE(deleteArgs.size(), 1);
+ QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+ // TemporaryItem is non-blocking, so the output (prompt) should be "/"
+ QCOMPARE(deleteArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
+ // make sure the item is gone
+ QCOMPARE(ifaceItem.call("Introspect").type(), QDBusMessage::ErrorMessage);
+
+ // make sure the ItemDeleted signal was sent
+ if (deletedSpy.size() < 1) {
+ deletedSpy.waitForSignal(5000);
+ }
+ QCOMPARE(deletedSpy.size(), 1);
+ QCOMPARE(deletedSpy.takeFirst(), itemPath);
+
+ // delete the collection
+ ifaceColl.call(QDBus::Block, "Delete");
+ // close the session
+ QDBusInterface("org.freedesktop.Secret", sessionPath.path()).call("Close");
+}
+
+void ServiceTest::reInitTestCase()
+{
+ // remove the TemporaryCollectionManager and replace it with a \
TempBlockingCollectionManager + m_master->removeManager(m_tempCollMan);
+ delete m_tempCollMan;
+ m_tempBlockCollMan = new TempBlockingCollectionManager(m_master);
+ m_master->addManager(m_tempBlockCollMan);
+}
+
+void ServiceTest::blockingCollection()
+{
+ ClientPrompt *prompt = 0;
+
+ QDBusInterface ifaceService("org.freedesktop.Secret", \
"/org/freedesktop/secrets"); + QVERIFY(ifaceService.isValid());
+
+ // create a session
+ // create a session
+ QDBusObjectPath sessionPath;
+ QList<QVariant> sessionInput;
+ sessionInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
+ QDBusMessage sessionReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession", + \
sessionInput); + sessionPath = \
sessionReply.arguments().at(1).value<QDBusObjectPath>(); +
+ // listen to CollectionCreated/CollectionDeleted/CollectionChanged signals
+ ObjectPathSignalSpy createdSpy(&ifaceService, \
SIGNAL(CollectionCreated(QDBusObjectPath))); + QVERIFY(createdSpy.isValid());
+ ObjectPathSignalSpy deletedSpy(&ifaceService, \
SIGNAL(CollectionDeleted(QDBusObjectPath))); + QVERIFY(deletedSpy.isValid());
+ ObjectPathSignalSpy changedSpy(&ifaceService, \
SIGNAL(CollectionChanged(QDBusObjectPath))); + QVERIFY(changedSpy.isValid());
+
+ // create a collection
+ QDBusObjectPath promptPath;
+ QMap<QString, QVariant> createProperties;
+ QList<QVariant> createInput;
+ createProperties["Label"] = "test";
+ createProperties["Locked"] = false; // create collection unlocked
+ createInput << QVariant::fromValue(createProperties);
+ QDBusMessage createReply = ifaceService.callWithArgumentList(QDBus::Block, \
"CreateCollection", + \
createInput); + QCOMPARE(createReply.type(), QDBusMessage::ReplyMessage);
+ QList<QVariant> createArgs = createReply.arguments();
+ QCOMPARE(createArgs.size(), 2);
+ QCOMPARE(createArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+ QCOMPARE(createArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
+ // TempBlockingCollection is blocking, so the first output (path) should be "/".
+ QCOMPARE(createArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
+ promptPath = createArgs.at(1).value<QDBusObjectPath>();
+ QVERIFY(promptPath.path().startsWith(
+ QLatin1String("/org/freedesktop/secrets/prompts/")));
+
+ // dismiss the prompt and wait for the result.
+ prompt = new ClientPrompt(promptPath);
+ prompt->dismissAndWait(5000);
+ QVERIFY(prompt->completed());
+ QVERIFY(prompt->dismissed());
+ delete prompt;
+
+ createReply = ifaceService.callWithArgumentList(QDBus::Block, "CreateCollection",
+ createInput);
+ QCOMPARE(createReply.type(), QDBusMessage::ReplyMessage);
+ createArgs = createReply.arguments();
+ QCOMPARE(createArgs.size(), 2);
+ QCOMPARE(createArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+ QCOMPARE(createArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
+ // TempBlockingCollection is blocking, so the first output (path) should be "/".
+ QCOMPARE(createArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
+ promptPath = createArgs.at(1).value<QDBusObjectPath>();
+ QVERIFY(promptPath.path().startsWith(
+ QLatin1String("/org/freedesktop/secrets/prompts/")));
+
+ // prompt and wait for the result.
+ prompt = new ClientPrompt(promptPath);
+ prompt->promptAndWait(5000);
+ QVERIFY(prompt->completed());
+ QVERIFY(!prompt->dismissed());
+ QCOMPARE(prompt->result().userType(), qMetaTypeId<QDBusObjectPath>());
+ QDBusObjectPath collectionPath = prompt->result().value<QDBusObjectPath>();
+ QVERIFY(collectionPath.path().startsWith(
+ QLatin1String("/org/freedesktop/secrets/collection/")));
+ QDBusInterface ifaceCollection("org.freedesktop.Secret", collectionPath.path(),
+ "org.freedesktop.Secret.Collection");
+ QVERIFY(ifaceCollection.isValid());
+ delete prompt;
+
+ // make sure the CollectionCreated signal was sent
+ if (createdSpy.size() < 1) {
+ createdSpy.waitForSignal(5000);
+ }
+ QCOMPARE(createdSpy.size(), 1);
+ QCOMPARE(createdSpy.takeFirst(), collectionPath);
+
+ // read collection properties
+ QVariant propItems = ifaceCollection.property("Items");
+ QVERIFY(propItems.isValid());
+ QVERIFY(propItems.canConvert<QList<QDBusObjectPath> >());
+ QList<QDBusObjectPath> propItemsList = propItems.value<QList<QDBusObjectPath> \
>(); + QVERIFY(propItemsList.isEmpty());
+ QVariant propLabel = ifaceCollection.property("Label");
+ QVERIFY(propLabel.isValid());
+ QCOMPARE(propLabel.type(), QVariant::String);
+ QCOMPARE(propLabel.value<QString>(), QString("test"));
+ QVariant propLocked = ifaceCollection.property("Locked");
+ QVERIFY(propLocked.isValid());
+ QCOMPARE(propLocked.value<bool>(), false);
+ QVariant propCreated = ifaceCollection.property("Created");
+ QVERIFY(propCreated.isValid());
+ QCOMPARE(propCreated.type(), QVariant::ULongLong);
+ qulonglong propCreatedUll = propCreated.value<qulonglong>();
+ QVERIFY(QDateTime::currentDateTime().toTime_t() - propCreatedUll < 60);
+ QVariant propModified = ifaceCollection.property("Modified");
+ QVERIFY(propModified.isValid());
+ QCOMPARE(propModified.type(), QVariant::ULongLong);
+ QCOMPARE(propModified.value<qulonglong>(), propCreatedUll);
+
+ // set the label and re-read it.
+ ifaceCollection.setProperty("Label", QString("test2"));
+ propLabel = ifaceCollection.property("Label");
+ QVERIFY(propLabel.isValid());
+ QCOMPARE(propLabel.type(), QVariant::String);
+ QCOMPARE(propLabel.value<QString>(), QString("test2"));
+
+ // make sure the CollectionChanged signal was sent
+ if (changedSpy.size() < 1) {
+ changedSpy.waitForSignal(5000);
+ }
+ QCOMPARE(changedSpy.size(), 1);
+ QCOMPARE(changedSpy.takeFirst(), collectionPath);
+
+ // delete the collection
+ QDBusMessage deleteReply = ifaceCollection.call(QDBus::Block, "Delete");
+ QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
+ QList<QVariant> deleteArgs = deleteReply.arguments();
+ QCOMPARE(deleteArgs.size(), 1);
+ QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+ // TempBlockingCollection is blocking, so the output (prompt) should be a valid \
one. + promptPath = deleteArgs.at(0).value<QDBusObjectPath>();
+ QVERIFY(promptPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/prompts/")));
+
+ // dismiss the prompt and wait for the result.
+ prompt = new ClientPrompt(promptPath);
+ prompt->dismissAndWait(5000);
+ QVERIFY(prompt->completed());
+ QVERIFY(prompt->dismissed());
+ delete prompt;
+
+ // retry and complete the prompt this time
+ deleteReply = ifaceCollection.call(QDBus::Block, "Delete");
+ QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
+ deleteArgs = deleteReply.arguments();
+ QCOMPARE(deleteArgs.size(), 1);
+ QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+ // TempBlockingCollection is blocking, so the output (prompt) should be a valid \
one. + promptPath = deleteArgs.at(0).value<QDBusObjectPath>();
+ QVERIFY(promptPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/prompts/")));
+ prompt = new ClientPrompt(promptPath);
+ prompt->promptAndWait(5000);
+ QVERIFY(prompt->completed());
+ QVERIFY(!prompt->dismissed());
+ delete prompt;
+
+ // make sure the collection is gone
+ QCOMPARE(ifaceCollection.call("Introspect").type(), QDBusMessage::ErrorMessage);
+
+ // make sure the CollectionDeleted signal was sent
+ if (deletedSpy.size() < 1) {
+ deletedSpy.waitForSignal(5000);
+ }
+ QCOMPARE(deletedSpy.size(), 1);
+ QCOMPARE(deletedSpy.takeFirst(), collectionPath);
+
+ // close the session
+ QDBusInterface("org.freedesktop.Secret", sessionPath.path()).call("Close");
+}
+
+void ServiceTest::blockingItem()
+{
+ // TODO: test
+}
+
+void ServiceTest::cleanupTestCase()
+{
+ delete m_service;
+ delete m_master;
+
+ QCA::deinit();
+}
+
+QTEST_KDEMAIN_CORE(ServiceTest)
+
+ObjectPathSignalSpy::ObjectPathSignalSpy(QDBusAbstractInterface *iface,
+ const char *signal)
+{
+ m_valid = connect(iface, signal, SLOT(slotReceived(QDBusObjectPath)));
+}
+
+bool ObjectPathSignalSpy::isValid() const
+{
+ return m_valid;
+}
+
+void ObjectPathSignalSpy::waitForSignal(int time)
+{
+ waitForSignals(1, time);
+}
+
+void ObjectPathSignalSpy::waitForSignals(int num, int time)
+{
+ m_numWaiting = num;
+ if (count() < m_numWaiting)
+ {
+ QEventLoop loop;
+ loop.connect(this, SIGNAL(doneWaiting()), SLOT(quit()));
+ QTimer::singleShot(time, &loop, SLOT(quit()));
+ loop.exec();
+ }
+}
+
+void ObjectPathSignalSpy::slotReceived(const QDBusObjectPath &objectPath)
+{
+ append(objectPath);
+ if (count() >= m_numWaiting) {
+ emit doneWaiting();
+ }
+}
+
+ClientPrompt::ClientPrompt(QDBusObjectPath promptPath)
+ : m_completed(false), m_dismissed(false),
+ m_interface("org.freedesktop.Secret", promptPath.path())
+{
+ Q_ASSERT(m_interface.isValid());
+ connect(&m_interface, SIGNAL(Completed(bool, QDBusVariant)),
+ SLOT(slotCompleted(bool, QDBusVariant)));
+}
+
+void ClientPrompt::promptAndWait(int time)
+{
+ QDBusMessage reply = m_interface.call(QDBus::Block, "Prompt", QString(""));
+ Q_ASSERT(reply.type() == QDBusMessage::ReplyMessage);
+ justWait(time);
+}
+
+void ClientPrompt::dismissAndWait(int time)
+{
+ QDBusMessage reply = m_interface.call(QDBus::Block, "Dismiss");
+ Q_ASSERT(reply.type() == QDBusMessage::ReplyMessage);
+ justWait(time);
+}
+
+void ClientPrompt::slotCompleted(bool dismissed, const QDBusVariant &result)
+{
+ m_completed = true;
+ m_dismissed = dismissed;
+ m_result = result.variant();
+ m_loop.quit();
+}
+
+void ClientPrompt::justWait(int time)
+{
+ if (time > 0) {
+ QTimer::singleShot(time, &m_loop, SLOT(quit()));
+ }
+ m_loop.exec();
+}
+
+#include "servicetest.moc"
diff --git a/frontend/tests/servicetest.h b/frontend/tests/servicetest.h
new file mode 100644
index 0000000..4f9dbb3
--- /dev/null
+++ b/frontend/tests/servicetest.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SERVICETEST_H
+#define SERVICETEST_H
+
+#include <QtCore/QObject>
+#include <QtCore/QList>
+#include <QtCore/QVariant>
+#include <QtCore/QEventLoop>
+#include <QtDBus/QDBusVariant>
+#include <QtDBus/QDBusObjectPath>
+#include <QtDBus/QDBusInterface>
+
+class BackendMaster;
+class TemporaryCollectionManager;
+class TempBlockingCollectionManager;
+class Service;
+class QDBusAbstractInterface;
+
+/**
+ * Unit-test for the fd.o Secret daemon
+ */
+class ServiceTest : public QObject
+{
+ Q_OBJECT
+
+private:
+ BackendMaster *m_master;
+ TemporaryCollectionManager *m_tempCollMan;
+ TempBlockingCollectionManager *m_tempBlockCollMan;
+ Service *m_service;
+
+private Q_SLOTS:
+ // create services and collections needed for testing
+ void initTestCase();
+
+ // check if Service is registered with D-Bus
+ void dbusService();
+
+ // open various sessions, make sure they are available on the bus, then close \
them. + void session();
+
+ // create and remove collections
+ void nonBlockingCollection();
+
+ // create and remove items
+ void nonBlockingItem();
+
+ // change some of the parameters of the testcase needed for the tests to come
+ void reInitTestCase();
+
+ // create and remove blocking collections
+ void blockingCollection();
+
+ // create and remove blocking items
+ void blockingItem();
+
+ // cleanup
+ void cleanupTestCase();
+};
+
+/**
+ * Listens to D-Bus signals which only have an object-path
+ * as only argument.
+ */
+class ObjectPathSignalSpy : public QObject, public QList<QDBusObjectPath>
+{
+ Q_OBJECT
+
+public:
+ // constructor. similar to QSignalSpy's constructor.
+ ObjectPathSignalSpy(QDBusAbstractInterface *iface, const char *signal);
+
+ // return true if the connection to the signal was successful
+ bool isValid() const;
+
+ // wait a specified number of ms for the signal to be received.
+ void waitForSignal(int time);
+
+ // wait a specified number of ms for multiple signals to be received
+ void waitForSignals(int num, int time);
+
+Q_SIGNALS:
+ // stop waiting for the signal.
+ void doneWaiting();
+
+private Q_SLOTS:
+ // Single slot which receives all of the various signals.
+ void slotReceived(const QDBusObjectPath &objectPath);
+
+private:
+ bool m_valid;
+ int m_numWaiting;
+};
+
+/**
+ * Client mini-stub for org.freedesktop.Secret.Prompt.
+ */
+class ClientPrompt : public QObject
+{
+ Q_OBJECT
+
+public:
+ // constructor. wraps around the prompt at promptPath.
+ ClientPrompt(QDBusObjectPath promptPath);
+
+ // Call the Prompt method and wait some time for completion
+ // (sends bogus window-id)
+ void promptAndWait(int time);
+
+ // Call the Dismiss method and wait some time for completion
+ void dismissAndWait(int time);
+
+ // check if the call has been completed
+ bool completed() const {
+ return m_completed;
+ }
+
+ // check if the call was dismissed
+ bool dismissed() const {
+ return m_dismissed;
+ }
+
+ // get the call's result
+ const QVariant &result() const {
+ return m_result;
+ }
+
+private Q_SLOTS:
+ // listens for Completed signals of the D-Bus prompt.
+ void slotCompleted(bool dismissed, const QDBusVariant &result);
+
+private:
+ // just wait (called by *AndWait methods)
+ void justWait(int time);
+
+ bool m_completed;
+ bool m_dismissed;
+ QVariant m_result;
+ QDBusInterface m_interface;
+ QEventLoop m_loop;
+};
+
+#endif
diff --git a/frontend/tests/tempblockingcollection.cpp \
b/frontend/tests/tempblockingcollection.cpp new file mode 100644
index 0000000..8169aaa
--- /dev/null
+++ b/frontend/tests/tempblockingcollection.cpp
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "tempblockingcollection.h"
+#include "tempblockingitem.h"
+#include "tempblockingjobs.h"
+
+#include <secrettool.h>
+
+TempBlockingCollection::TempBlockingCollection(const QString &id, \
BackendCollectionManager *parent) + : BackendCollection(parent)
+{
+ m_id = id;
+ QDateTime now = QDateTime::currentDateTime();
+ m_created = now;
+ m_modified = now;
+}
+
+TempBlockingCollection::~TempBlockingCollection()
+{
+}
+
+QString TempBlockingCollection::id() const
+{
+ return m_id;
+}
+
+BackendReturn<QString> TempBlockingCollection::label() const
+{
+ return m_label;
+}
+
+BackendReturn<void> TempBlockingCollection::setLabel(const QString &label)
+{
+ m_label = label;
+ emit collectionChanged(this);
+ return BackendReturn<void>();
+}
+
+QDateTime TempBlockingCollection::created() const
+{
+ return m_created;
+}
+
+QDateTime TempBlockingCollection::modified() const
+{
+ return m_modified;
+}
+
+bool TempBlockingCollection::isLocked() const
+{
+ return false;
+}
+
+BackendReturn<QList<BackendItem*> > TempBlockingCollection::items() const
+{
+ return m_items;
+}
+
+BackendReturn<QList<BackendItem*> > TempBlockingCollection::searchItems(
+ const QMap<QString, QString> &attributes) const
+{
+ TempBlockingItem *titem;
+ QList<BackendItem*> foundItems;
+ Q_FOREACH(BackendItem *item, m_items) {
+ titem = qobject_cast<TempBlockingItem*>(item);
+ if (titem && titem->matches(attributes)) {
+ foundItems.append(item);
+ }
+ }
+ return foundItems;
+}
+
+UnlockCollectionJob *TempBlockingCollection::createUnlockJob()
+{
+ return new TempBlockingUnlockCollectionJob(this);
+}
+
+LockCollectionJob *TempBlockingCollection::createLockJob()
+{
+ return new TempBlockingLockCollectionJob(this);
+}
+
+DeleteCollectionJob *TempBlockingCollection::createDeleteJob()
+{
+ TempBlockingDeleteCollectionJob *job = new TempBlockingDeleteCollectionJob(this);
+ connect(job, SIGNAL(result(QueuedJob*)),
+ SLOT(deleteCollectionJobResult(QueuedJob*)));
+ return job;
+}
+
+CreateItemJob *TempBlockingCollection::createCreateItemJob(const QString &label,
+ const QMap<QString, \
QString> &attributes, + \
const QCA::SecureArray &secret, + \
bool locked, bool replace) +{
+ return new TempBlockingCreateItemJob(label, attributes, secret, locked, replace, \
this); +}
+
+ChangeAuthenticationCollectionJob \
*TempBlockingCollection::createChangeAuthenticationJob() +{
+ return new TempBlockingChangeAuthenticationCollectionJob(this);
+}
+
+BackendReturn<BackendItem*> TempBlockingCollection::createItem(const QString &label,
+ const QMap<QString, \
QString> &attributes, + \
const QCA::SecureArray &secret, + \
bool locked, bool replace) +{
+ Q_UNUSED(locked);
+
+ TempBlockingItem *item = 0;
+ bool replacing = false;
+
+ // check for duplicates
+ BackendReturn<QList<BackendItem*> > foundItems = searchItems(attributes);
+ if (!foundItems.isError() && foundItems.value().size() > 0) {
+ QList<BackendItem*> oldlist = foundItems.value();
+ Q_FOREACH(BackendItem* olditem, oldlist) {
+ if (olditem->attributes().value() == attributes) {
+ if (replace) {
+ // replacing an existing item
+ item = qobject_cast<TempBlockingItem*>(olditem);
+ replacing = true;
+ } else {
+ // item existing but should not be replaced
+ return BackendReturn<BackendItem*>(0, ErrorAlreadyExists);
+ }
+ break;
+ }
+ }
+ }
+
+ if (!item) {
+ item = new TempBlockingItem(createId(), this);
+ }
+ item->blockSignals(true);
+ item->setLabel(label);
+ item->setAttributes(attributes);
+ item->setSecret(secret);
+ item->blockSignals(false);
+
+ if (replacing) {
+ emit itemChanged(item);
+ } else {
+ m_items.append(item);
+ // new item, signals need to be wired
+ connect(item, SIGNAL(itemDeleted(BackendItem*)), \
SLOT(slotItemDeleted(BackendItem*))); + connect(item, \
SIGNAL(itemChanged(BackendItem*)), SIGNAL(itemChanged(BackendItem*))); + emit \
itemCreated(item); + }
+
+ return item;
+}
+
+void TempBlockingCollection::slotItemDeleted(BackendItem *item)
+{
+ m_items.removeAll(item);
+ emit itemDeleted(item);
+}
+
+void TempBlockingCollection::deleteCollectionJobResult(QueuedJob *job)
+{
+ TempBlockingDeleteCollectionJob * dcj = \
qobject_cast<TempBlockingDeleteCollectionJob*>(job); + Q_ASSERT(dcj);
+ if (!dcj->result()) {
+ return;
+ }
+ emit collectionDeleted(this);
+}
+
+#include "tempblockingcollection.moc"
diff --git a/frontend/tests/tempblockingcollection.h \
b/frontend/tests/tempblockingcollection.h new file mode 100644
index 0000000..7a71c2b
--- /dev/null
+++ b/frontend/tests/tempblockingcollection.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TEMPBLOCKINGCOLLECTION_H
+#define TEMPBLOCKINGCOLLECTION_H
+
+#include "backend/backendcollection.h"
+
+// implement a temporary collection that blocks every call.
+class TempBlockingCollection : public BackendCollection
+{
+ Q_OBJECT
+
+public:
+ TempBlockingCollection(const QString &id, BackendCollectionManager *parent);
+ virtual ~TempBlockingCollection();
+ virtual QString id() const;
+ virtual BackendReturn<QString> label() const;
+ virtual BackendReturn<void> setLabel(const QString &label);
+ virtual QDateTime created() const;
+ virtual QDateTime modified() const;
+ virtual bool isLocked() const;
+ virtual BackendReturn<QList<BackendItem*> > items() const;
+ virtual BackendReturn<QList<BackendItem*> > searchItems(const QMap<QString, \
QString> &attributes) const; + virtual UnlockCollectionJob *createUnlockJob();
+ virtual LockCollectionJob *createLockJob();
+ virtual DeleteCollectionJob *createDeleteJob();
+ virtual CreateItemJob *createCreateItemJob(const QString &label,
+ const QMap<QString, QString> \
&attributes, + const QCA::SecureArray \
&secret, bool locked, + bool replace);
+ virtual ChangeAuthenticationCollectionJob *createChangeAuthenticationJob();
+
+protected:
+ BackendReturn<BackendItem*> createItem(const QString &label,
+ const QMap<QString, QString> &attributes,
+ const QCA::SecureArray &secret, bool \
locked, + bool replace);
+
+private Q_SLOTS:
+ void slotItemDeleted(BackendItem *item);
+ void deleteCollectionJobResult(QueuedJob *job);
+
+private:
+ friend class TempBlockingCreateItemJob;
+
+ QString m_id;
+ QString m_label;
+ QDateTime m_created;
+ QDateTime m_modified;
+
+ QList<BackendItem*> m_items;
+};
+
+#endif
diff --git a/frontend/tests/tempblockingcollectionmanager.cpp \
b/frontend/tests/tempblockingcollectionmanager.cpp new file mode 100644
index 0000000..3c57fad
--- /dev/null
+++ b/frontend/tests/tempblockingcollectionmanager.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "tempblockingcollectionmanager.h"
+#include "tempblockingcollection.h"
+#include "tempblockingjobs.h"
+
+#include <secrettool.h>
+
+TempBlockingCollectionManager::TempBlockingCollectionManager(QObject *parent)
+ : BackendCollectionManager(parent)
+{
+}
+
+TempBlockingCollectionManager::~TempBlockingCollectionManager()
+{
+}
+
+CreateCollectionJob *TempBlockingCollectionManager::createCreateCollectionJob(const \
QString &label, + \
bool locked) +{
+ TempBlockingCreateCollectionJob *job = new TempBlockingCreateCollectionJob(label,
+ \
locked, + \
this); + connect(job, SIGNAL(result(QueuedJob*)),
+ SLOT(createCollectionJobResult(QueuedJob*)));
+ return job;
+}
+
+void TempBlockingCollectionManager::createCollectionJobResult(QueuedJob *job)
+{
+ CreateCollectionJob *ccj = qobject_cast<CreateCollectionJob*>(job);
+ Q_ASSERT(ccj);
+
+ if (!ccj->collection()) {
+ return;
+ }
+
+ // connect signals
+ connect(ccj->collection(), SIGNAL(collectionDeleted(BackendCollection*)),
+ SIGNAL(collectionDeleted(BackendCollection*)));
+ emit collectionCreated(ccj->collection());
+}
+
+#include "tempblockingcollectionmanager.moc"
diff --git a/frontend/tests/tempblockingcollectionmanager.h \
b/frontend/tests/tempblockingcollectionmanager.h new file mode 100644
index 0000000..4272d29
--- /dev/null
+++ b/frontend/tests/tempblockingcollectionmanager.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TEMPBLOCKINGCOLLECTIONMANAGER_H
+#define TEMPBLOCKINGCOLLECTIONMANAGER_H
+
+#include "backend/backendcollectionmanager.h"
+
+class TempBlockingCollection;
+
+// implement a temporary collection manager that blocks every call.
+class TempBlockingCollectionManager : public BackendCollectionManager
+{
+ Q_OBJECT
+
+public:
+ friend class TempBlockingCollection;
+
+public:
+ TempBlockingCollectionManager(QObject *parent = 0);
+ virtual ~TempBlockingCollectionManager();
+ virtual CreateCollectionJob *createCreateCollectionJob(const QString &label,
+ bool locked);
+
+private Q_SLOTS:
+ void createCollectionJobResult(QueuedJob *job);
+};
+
+#endif
diff --git a/frontend/tests/tempblockingitem.cpp \
b/frontend/tests/tempblockingitem.cpp new file mode 100644
index 0000000..b819bd3
--- /dev/null
+++ b/frontend/tests/tempblockingitem.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "tempblockingitem.h"
+#include "tempblockingcollection.h"
+#include "tempblockingjobs.h"
+
+TempBlockingItem::TempBlockingItem(const QString &id, TempBlockingCollection \
*parent) + : BackendItem(parent), m_id(id)
+{
+ QDateTime now = QDateTime::currentDateTime();
+ m_created = now;
+ m_modified = now;
+}
+
+TempBlockingItem::~TempBlockingItem()
+{
+}
+
+QString TempBlockingItem::id() const
+{
+ return m_id;
+}
+
+BackendReturn<QString> TempBlockingItem::label() const
+{
+ return m_label;
+}
+
+BackendReturn<void> TempBlockingItem::setLabel(const QString &label)
+{
+ m_label = label;
+ markAsModified();
+ return BackendReturn<void>();
+}
+
+BackendReturn<QCA::SecureArray> TempBlockingItem::secret() const
+{
+ return m_secret;
+}
+
+BackendReturn<void> TempBlockingItem::setSecret(const QCA::SecureArray &secret)
+{
+ m_secret = secret;
+ markAsModified();
+ return BackendReturn<void>();
+}
+
+BackendReturn<QMap<QString, QString> > TempBlockingItem::attributes() const
+{
+ return m_attributes;
+}
+
+BackendReturn<void> TempBlockingItem::setAttributes(const QMap<QString, QString> \
&attributes) +{
+ m_attributes = attributes;
+ markAsModified();
+ return BackendReturn<void>();
+}
+
+QDateTime TempBlockingItem::created() const
+{
+ return m_created;
+}
+
+QDateTime TempBlockingItem::modified() const
+{
+ return m_modified;
+}
+
+bool TempBlockingItem::isLocked() const
+{
+ return false;
+}
+
+UnlockItemJob *TempBlockingItem::createUnlockJob()
+{
+ return new TempBlockingUnlockItemJob(this);
+}
+
+LockItemJob *TempBlockingItem::createLockJob()
+{
+ return new TempBlockingLockItemJob(this);
+}
+
+DeleteItemJob *TempBlockingItem::createDeleteJob()
+{
+ TempBlockingDeleteItemJob *job = new TempBlockingDeleteItemJob(this);
+ connect(job, SIGNAL(result(QueuedJob*)), SLOT(deleteItemJobResult(QueuedJob*)));
+ return job;
+}
+
+ChangeAuthenticationItemJob *TempBlockingItem::createChangeAuthenticationJob()
+{
+ return new TempBlockingChangeAuthenticationItemJob(this);
+}
+
+bool TempBlockingItem::matches(const QMap<QString, QString> &attributes)
+{
+ QMap<QString, QString>::const_iterator it = attributes.constBegin();
+ QMap<QString, QString>::const_iterator end = attributes.constEnd();
+ for ( ; it != end; ++it) {
+ if (!m_attributes.contains(it.key()) ||
+ m_attributes.value(it.key()) != it.value()) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void TempBlockingItem::deleteItemJobResult(QueuedJob *job)
+{
+ TempBlockingDeleteItemJob *dij = qobject_cast<TempBlockingDeleteItemJob*>(job);
+ Q_ASSERT(dij);
+ if (!dij->result()) {
+ return;
+ }
+ emit itemDeleted(this);
+}
+
+void TempBlockingItem::markAsModified()
+{
+ m_modified = QDateTime::currentDateTime();
+ emit itemChanged(this);
+}
+
+#include "tempblockingitem.moc"
diff --git a/frontend/tests/tempblockingitem.h b/frontend/tests/tempblockingitem.h
new file mode 100644
index 0000000..1b16a0c
--- /dev/null
+++ b/frontend/tests/tempblockingitem.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TEMPBLOCKINGITEM_H
+#define TEMPBLOCKINGITEM_H
+
+#include "backend/backenditem.h"
+
+class TempBlockingCollection;
+
+// temporary item that blocks every call
+class TempBlockingItem : public BackendItem
+{
+ Q_OBJECT
+
+public:
+ friend class TempBlockingCollection;
+
+ TempBlockingItem(const QString &id, TempBlockingCollection *parent);
+ ~TempBlockingItem();
+ virtual QString id() const;
+ virtual BackendReturn<QString> label() const;
+ virtual BackendReturn<void> setLabel(const QString &label);
+ virtual BackendReturn<QCA::SecureArray> secret() const;
+ virtual BackendReturn<void> setSecret(const QCA::SecureArray &secret);
+ virtual BackendReturn<QMap<QString, QString> > attributes() const;
+ virtual BackendReturn<void> setAttributes(const QMap<QString, QString> \
&attributes); + virtual QDateTime created() const;
+ virtual QDateTime modified() const;
+ virtual bool isLocked() const;
+ virtual UnlockItemJob *createUnlockJob();
+ virtual LockItemJob *createLockJob();
+ virtual DeleteItemJob *createDeleteJob();
+ virtual ChangeAuthenticationItemJob *createChangeAuthenticationJob();
+ bool matches(const QMap<QString, QString> &attributes);
+
+private Q_SLOTS:
+ void deleteItemJobResult(QueuedJob *job);
+
+private:
+ void markAsModified();
+
+ QString m_id;
+ QString m_label;
+ QDateTime m_created;
+ QDateTime m_modified;
+ QMap<QString, QString> m_attributes;
+
+ QCA::SecureArray m_secret;
+};
+
+#endif
diff --git a/frontend/tests/tempblockingjobs.cpp \
b/frontend/tests/tempblockingjobs.cpp new file mode 100644
index 0000000..47382e2
--- /dev/null
+++ b/frontend/tests/tempblockingjobs.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "tempblockingjobs.h"
+
+#include <secrettool.h>
+
+#include <QtCore/QTimer>
+
+TempBlockingCreateCollectionJob::TempBlockingCreateCollectionJob(const QString \
&label, bool locked, + \
TempBlockingCollectionManager *manager) + : CreateCollectionJob(label, locked, \
manager) +{
+}
+
+void TempBlockingCreateCollectionJob::perform()
+{
+ TempBlockingCollection *coll = new TempBlockingCollection(createId(), manager());
+ coll->setLabel(label());
+
+ setCollection(coll);
+ emitResult();
+}
+
+TempBlockingUnlockCollectionJob::TempBlockingUnlockCollectionJob(BackendCollection* \
coll) + : UnlockCollectionJob(coll)
+{
+}
+
+void TempBlockingUnlockCollectionJob::perform()
+{
+ setResult(true);
+ emitResult();
+}
+
+TempBlockingLockCollectionJob::TempBlockingLockCollectionJob(BackendCollection* \
coll) + : LockCollectionJob(coll)
+{
+}
+
+void TempBlockingLockCollectionJob::perform()
+{
+ setError(ErrorNotSupported);
+ setResult(false);
+ emitResult();
+}
+
+TempBlockingDeleteCollectionJob::TempBlockingDeleteCollectionJob(BackendCollection* \
coll) + : DeleteCollectionJob(coll)
+{
+}
+
+void TempBlockingDeleteCollectionJob::perform()
+{
+ setResult(true);
+ collection()->deleteLater();
+ emitResult();
+}
+
+TempBlockingChangeAuthenticationCollectionJob::TempBlockingChangeAuthenticationCollectionJob(BackendCollection* \
coll) + : ChangeAuthenticationCollectionJob(coll)
+{
+}
+
+void TempBlockingChangeAuthenticationCollectionJob::perform()
+{
+ setError(ErrorNotSupported);
+ setResult(false);
+ emitResult();
+}
+
+TempBlockingCreateItemJob::TempBlockingCreateItemJob(const QString& label,
+ const QMap< QString, QString >& \
attributes, + const \
QCA::SecureArray& secret, bool locked, + \
bool replace, + \
TempBlockingCollection* collection) + : CreateItemJob(label, attributes, secret, \
locked, replace, collection), + m_tempColl(collection)
+{
+}
+
+void TempBlockingCreateItemJob::perform()
+{
+ BackendReturn<BackendItem*> rc = m_tempColl->createItem(label(), attributes(),
+ secret(), locked(),
+ replace());
+
+ if (rc.isError()) {
+ setError(rc.error(), rc.errorMessage());
+ } else {
+ setItem(rc.value());
+ }
+ emitResult();
+}
+
+TempBlockingUnlockItemJob::TempBlockingUnlockItemJob(BackendItem* item)
+ : UnlockItemJob(item)
+{
+}
+
+void TempBlockingUnlockItemJob::perform()
+{
+ setResult(true);
+ emitResult();
+}
+
+TempBlockingLockItemJob::TempBlockingLockItemJob(BackendItem* item)
+ : LockItemJob(item)
+{
+}
+
+void TempBlockingLockItemJob::perform()
+{
+ setError(ErrorNotSupported);
+ setResult(false);
+ emitResult();
+}
+
+TempBlockingDeleteItemJob::TempBlockingDeleteItemJob(BackendItem* item)
+ : DeleteItemJob(item)
+{
+}
+
+void TempBlockingDeleteItemJob::perform()
+{
+ setResult(true);
+ item()->deleteLater();
+ emitResult();
+}
+
+TempBlockingChangeAuthenticationItemJob::TempBlockingChangeAuthenticationItemJob(BackendItem* \
item) + : ChangeAuthenticationItemJob(item)
+{
+}
+
+void TempBlockingChangeAuthenticationItemJob::perform()
+{
+ setError(ErrorNotSupported);
+ setResult(false);
+ emitResult();
+}
+
+#include "tempblockingjobs.moc"
diff --git a/frontend/tests/tempblockingjobs.h b/frontend/tests/tempblockingjobs.h
new file mode 100644
index 0000000..bf04014
--- /dev/null
+++ b/frontend/tests/tempblockingjobs.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TEMPBLOCKINGJOBS_H
+#define TEMPBLOCKINGJOBS_H
+
+#include "tempblockingcollectionmanager.h"
+#include "tempblockingcollection.h"
+#include "tempblockingitem.h"
+
+#include <QtCore/QTimer>
+
+class TempBlockingCreateCollectionJob : public CreateCollectionJob
+{
+ Q_OBJECT
+
+public:
+ TempBlockingCreateCollectionJob(const QString &label, bool locked,
+ TempBlockingCollectionManager *manager);
+ virtual bool isImmediate() const { return false; }
+ virtual void exec() { Q_ASSERT(false); }
+ virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+ void perform();
+};
+
+class TempBlockingUnlockCollectionJob : public UnlockCollectionJob
+{
+ Q_OBJECT
+
+public:
+ TempBlockingUnlockCollectionJob(BackendCollection *coll);
+ virtual bool isImmediate() const { return false; }
+ virtual void exec() { Q_ASSERT(false); }
+ virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+ void perform();
+};
+
+class TempBlockingDeleteCollectionJob : public DeleteCollectionJob
+{
+ Q_OBJECT
+
+public:
+ TempBlockingDeleteCollectionJob(BackendCollection *coll);
+ virtual bool isImmediate() const { return false; }
+ virtual void exec() { Q_ASSERT(false); }
+ virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+ void perform();
+};
+
+class TempBlockingLockCollectionJob : public LockCollectionJob
+{
+ Q_OBJECT
+
+public:
+ TempBlockingLockCollectionJob(BackendCollection *coll);
+ virtual bool isImmediate() const { return false; }
+ virtual void exec() { Q_ASSERT(false); }
+ virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+ void perform();
+};
+
+class TempBlockingChangeAuthenticationCollectionJob : public \
ChangeAuthenticationCollectionJob +{
+ Q_OBJECT
+
+public:
+ TempBlockingChangeAuthenticationCollectionJob(BackendCollection *coll);
+ virtual bool isImmediate() const { return false; }
+ virtual void exec() { Q_ASSERT(false); }
+ virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+ void perform();
+};
+
+class TempBlockingCreateItemJob : public CreateItemJob
+{
+ Q_OBJECT
+
+public:
+ TempBlockingCreateItemJob(const QString &label, const QMap<QString, QString> \
&attributes, + const QCA::SecureArray &secret, bool \
locked, bool replace, + TempBlockingCollection \
*collection); + virtual bool isImmediate() const { return false; }
+ virtual void exec() { Q_ASSERT(false); }
+ virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+ void perform();
+
+private:
+ TempBlockingCollection* m_tempColl;
+};
+
+class TempBlockingUnlockItemJob : public UnlockItemJob
+{
+ Q_OBJECT
+
+public:
+ TempBlockingUnlockItemJob(BackendItem *item);
+ virtual bool isImmediate() const { return false; }
+ virtual void exec() { Q_ASSERT(false); }
+ virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+ void perform();
+};
+
+class TempBlockingLockItemJob : public LockItemJob
+{
+ Q_OBJECT
+
+public:
+ TempBlockingLockItemJob(BackendItem *item);
+ virtual bool isImmediate() const { return false; }
+ virtual void exec() { Q_ASSERT(false); }
+ virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+ void perform();
+};
+
+class TempBlockingDeleteItemJob : public DeleteItemJob
+{
+ Q_OBJECT
+
+public:
+ TempBlockingDeleteItemJob(BackendItem *item);
+ virtual bool isImmediate() const { return false; }
+ virtual void exec() { Q_ASSERT(false); }
+ virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+ void perform();
+};
+
+class TempBlockingChangeAuthenticationItemJob : public ChangeAuthenticationItemJob
+{
+ Q_OBJECT
+
+public:
+ TempBlockingChangeAuthenticationItemJob(BackendItem *item);
+ virtual bool isImmediate() const { return false; }
+ virtual void exec() { Q_ASSERT(false); }
+ virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+ void perform();
+};
+
+#endif
diff --git a/main.cpp b/main.cpp
index 0d9dd92..3088e10 100644
--- a/main.cpp
+++ b/main.cpp
@@ -27,7 +27,7 @@
#include "backend/backendmaster.h"
#include "backend/temporary/temporarycollectionmanager.h"
-#include "daemon/service.h"
+#include "frontend/secret/service.h"
int main(int argc, char **argv)
{
diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt
new file mode 100644
index 0000000..fdf1d61
--- /dev/null
+++ b/ui/CMakeLists.txt
@@ -0,0 +1,10 @@
+INCLUDE_DIRECTORIES (${CMAKE_CURRENT_SOURCE_DIR})
+ADD_SUBDIRECTORY (tests)
+
+SET (ksecretservice_ui_SRCS
+ abstractuijobs.cpp
+ dialoguifactory.cpp
+)
+
+KDE4_ADD_LIBRARY (ksecretserviceui STATIC ${ksecretservice_ui_SRCS})
+TARGET_LINK_LIBRARIES (ksecretserviceui ${KDE4_KDEUI_LIBS} ${QCA2_LIBRARIES})
diff --git a/ui/abstractuijobs.cpp b/ui/abstractuijobs.cpp
new file mode 100644
index 0000000..b8304b0
--- /dev/null
+++ b/ui/abstractuijobs.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "abstractuijobs.h"
+#include "abstractuimanager.h"
+
+#include <QtCore/QEventLoop>
+#include <QtCore/QTimer>
+
+AbstractUiJob::AbstractUiJob(AbstractUiManager *manager) : QueuedJob(manager)
+{
+}
+
+AbstractUiJob::~AbstractUiJob()
+{
+}
+
+void AbstractUiJob::exec()
+{
+ Q_ASSERT(false);
+}
+
+AbstractAskPasswordJob::AbstractAskPasswordJob(AbstractUiManager *manager,
+ const QString &collection,
+ bool secondTry)
+ : AbstractUiJob(manager), m_collection(collection), m_secondTry(secondTry)
+{
+}
+
+AbstractAskPasswordJob::~AbstractAskPasswordJob()
+{
+}
+
+const QString &AbstractAskPasswordJob::collection() const
+{
+ return m_collection;
+}
+
+bool AbstractAskPasswordJob::isSecondTry() const
+{
+ return m_secondTry;
+}
+
+bool AbstractAskPasswordJob::result() const
+{
+ return m_result;
+}
+
+const QCA::SecureArray &AbstractAskPasswordJob::password() const
+{
+ return m_password;
+}
+
+void AbstractAskPasswordJob::setResult(bool result)
+{
+ m_result = result;
+}
+
+void AbstractAskPasswordJob::setPassword(const QCA::SecureArray &password)
+{
+ m_password = password;
+}
+
+#include "abstractuijobs.moc"
diff --git a/ui/abstractuijobs.h b/ui/abstractuijobs.h
new file mode 100644
index 0000000..c9ad9aa
--- /dev/null
+++ b/ui/abstractuijobs.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ABSTRACTUIJOBS_H
+#define ABSTRACTUIJOBS_H
+
+#include <queuedjob.h>
+#include <jobqueue.h>
+
+#include <QtCore/QQueue>
+#include <QtCrypto/QtCrypto>
+#include <kglobal.h>
+#include <kjob.h>
+
+class AbstractUiManager;
+
+/*
+ * Abstract master-class of user interface jobs.
+ */
+class AbstractUiJob : public QueuedJob
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param manager user interface job manager and parent object
+ */
+ explicit AbstractUiJob(AbstractUiManager *manager);
+
+ /**
+ * Destructor.
+ */
+ virtual ~AbstractUiJob();
+
+ /**
+ * Default implementation for user interface jobs. As a ui job can rarely be
+ * run synchronously, exec() crashes.
+ */
+ virtual void exec();
+
+private:
+ friend class UiJobManager;
+};
+
+/**
+ * Job that asks a user for a password to unlock a collection.
+ */
+class AbstractAskPasswordJob : public AbstractUiJob
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param manager ui job manager and parent object
+ * @param collection label of the collection that should be opened
+ * @param secondTry set to true if this is not the user's first try to enter
+ * the password correctly
+ */
+ AbstractAskPasswordJob(AbstractUiManager *manager, const QString &collection,
+ bool secondTry);
+
+ /**
+ * Destructor.
+ */
+ virtual ~AbstractAskPasswordJob();
+
+ /**
+ * Get the label of the collection that's about to be unlocked.
+ */
+ const QString &collection() const;
+
+ /**
+ * Check whether this is not the user's first try to enter the password.
+ */
+ bool isSecondTry() const;
+
+ /**
+ * Get the result of the operation.
+ *
+ * @return true if the user entered a password, false if not
+ */
+ bool result() const;
+
+ /**
+ * Get the password the user entered.
+ *
+ * @return the password entered by the user or an empty array if the user
+ * didn't enter a password
+ */
+ const QCA::SecureArray &password() const;
+
+protected:
+ /**
+ * Set the result of the operation.
+ *
+ * @remarks this is used by derived classes
+ * @param result result of the operation
+ */
+ void setResult(bool result);
+
+ /**
+ * Set the password entered by the user.
+ *
+ * @remarks This is used by derived classes
+ * @param password password entered by the user
+ */
+ void setPassword(const QCA::SecureArray &password);
+
+private:
+ QString m_collection; // name of the collection to be unlocked
+ bool m_secondTry; // true if this is not the first try
+ bool m_result; // the result of the operation
+ QCA::SecureArray m_password; // the password entered by the user
+};
+
+#endif
diff --git a/ui/abstractuimanager.h b/ui/abstractuimanager.h
new file mode 100644
index 0000000..24e0d06
--- /dev/null
+++ b/ui/abstractuimanager.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ABSTRACTUIMANAGER_H
+#define ABSTRACTUIMANAGER_H
+
+#include "abstractuijobs.h"
+
+/**
+ * Abstract factory that provides means to create a user interface for the various
+ * backend classes.
+ *
+ * This class can be reimplemented to provide a standard UI, a stripped-down UI
+ * (probably for mobile devices) or even a bogus UI which can be used inside
+ * unit-tests.
+ */
+class AbstractUiManager : public JobQueue
+{
+public:
+ virtual ~AbstractUiManager()
+ {
+ // TODO: clean-up
+ };
+
+ /**
+ * Create a job for asking for user's password for unlocking a collection.
+ *
+ * @param collection label of the collection to be unlocked
+ * @param secondTry set to true if the user already entered a wrong password \
before + * @return a job which can be enqueued to ask the user for the unlock \
password + */
+ virtual AbstractAskPasswordJob *createAskPasswordJob(const QString &collection,
+ bool secondTry) = 0;
+};
+
+#endif
diff --git a/ui/dialoguifactory.cpp b/ui/dialoguifactory.cpp
new file mode 100644
index 0000000..ae12429
--- /dev/null
+++ b/ui/dialoguifactory.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dialoguifactory.h"
+
+#include <QtCore/QTimer>
+#include <kpassworddialog.h>
+
+AbstractAskPasswordJob* DialogUiFactory::createAskPasswordJob(const QString& \
collection, + bool \
secondTry) +{
+ return new DialogAskPasswordJob(this, collection, secondTry);
+}
+
+DialogAskPasswordJob::DialogAskPasswordJob(AbstractUiManager *manager,
+ const QString& collection,
+ bool secondTry)
+ : AbstractAskPasswordJob(manager, collection, secondTry), m_dialog(0)
+{
+}
+
+DialogAskPasswordJob::~DialogAskPasswordJob()
+{
+}
+
+void DialogAskPasswordJob::start()
+{
+ Q_ASSERT(!m_dialog);
+ // TODO: provide parent widget!
+ m_dialog = new KPasswordDialog;
+ m_dialog->setAttribute(Qt::WA_DeleteOnClose, true);
+ // TODO: needs proper string
+ m_dialog->setPrompt("Collection " + collection() + " wants password.");
+ connect(m_dialog, SIGNAL(finished(int)), this, SLOT(dialogFinished(int)));
+ m_dialog->show();
+}
+
+void DialogAskPasswordJob::dialogFinished(int result)
+{
+ Q_ASSERT(m_dialog);
+ if (result == QDialog::Accepted) {
+ setPassword(QCA::SecureArray(m_dialog->password().toUtf8()));
+ setResult(true);
+ } else {
+ setResult(false);
+ }
+ emitResult();
+}
+
+#include "dialoguifactory.moc"
diff --git a/ui/dialoguifactory.h b/ui/dialoguifactory.h
new file mode 100644
index 0000000..f3c4dc0
--- /dev/null
+++ b/ui/dialoguifactory.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DIALOGUIFACTORY_H
+#define DIALOGUIFACTORY_H
+
+#include "abstractuijobs.h"
+#include "abstractuimanager.h"
+
+class KPasswordDialog;
+
+class DialogAskPasswordJob : public AbstractAskPasswordJob
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor.
+ */
+ DialogAskPasswordJob(AbstractUiManager *manager, const QString& collection, bool \
secondTry); +
+ /**
+ * Destructor.
+ */
+ ~DialogAskPasswordJob();
+
+ /**
+ * Contains the actual workload of showing the dialog.
+ */
+ virtual void start();
+
+private Q_SLOTS:
+ /**
+ * Called when the dialog shown is either accepted or rejected.
+ */
+ void dialogFinished(int result);
+
+private:
+ KPasswordDialog *m_dialog;
+};
+
+/**
+ * Implement AbstractUiFactory to provide a user interface using dialogs.
+ */
+class DialogUiFactory : public AbstractUiManager
+{
+public:
+ /**
+ * Destructor.
+ */
+ virtual ~DialogUiFactory() {};
+
+ /**
+ * Create a job to ask for a user's password to unlock a collection.
+ */
+ virtual AbstractAskPasswordJob* createAskPasswordJob(const QString& collection,
+ bool secondTry);
+};
+
+#endif
diff --git a/ui/tests/CMakeLists.txt b/ui/tests/CMakeLists.txt
new file mode 100644
index 0000000..4faed32
--- /dev/null
+++ b/ui/tests/CMakeLists.txt
@@ -0,0 +1,10 @@
+INCLUDE_DIRECTORIES (${CMAKE_CURRENT_BINARY_DIR})
+
+# involves dialogs, thus not an automatic test
+KDE4_ADD_EXECUTABLE (dialoguifactory_test dialoguifactorytest.cpp)
+TARGET_LINK_LIBRARIES (dialoguifactory_test
+ ksecretservicelib
+ ksecretserviceui
+ ${QT_QTTEST_LIBRARIES}
+ ${KDE4_KDEUI_LIBS}
+)
diff --git a/ui/tests/dialoguifactorytest.cpp b/ui/tests/dialoguifactorytest.cpp
new file mode 100644
index 0000000..73f1a02
--- /dev/null
+++ b/ui/tests/dialoguifactorytest.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dialoguifactorytest.h"
+
+#include <QtCrypto/QtCrypto>
+#include <qtest_kde.h>
+
+#include "../dialoguifactory.h"
+
+void DialogUiFactoryTest::initTestCase()
+{
+ QCA::init();
+}
+
+void DialogUiFactoryTest::testAskPassword()
+{
+ DialogUiFactory fact;
+
+ // ask for a password (asynchronously)
+ AbstractAskPasswordJob *asyncJob1 = \
fact.createAskPasswordJob("TESTCOLLECTION-ASYNC1", false); + AbstractAskPasswordJob \
*asyncJob2 = fact.createAskPasswordJob("TESTCOLLECTION-ASYNC2", false); + \
QEventLoop loop; + connect(asyncJob2, SIGNAL(result(QueuedJob*)), &loop, \
SLOT(quit())); + asyncJob1->enqueue();
+ asyncJob2->enqueue();
+ loop.exec();
+}
+
+void DialogUiFactoryTest::cleanupTestCase()
+{
+}
+
+QTEST_KDEMAIN(DialogUiFactoryTest, GUI)
+#include "dialoguifactorytest.moc"
diff --git a/ui/tests/dialoguifactorytest.h b/ui/tests/dialoguifactorytest.h
new file mode 100644
index 0000000..d862ea7
--- /dev/null
+++ b/ui/tests/dialoguifactorytest.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DIALOGUIFACTORYTEST_H
+#define DIALOGUIFACTORYTEST_H
+
+#include <QtTest>
+
+class DialogUiFactoryTest : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void initTestCase();
+
+ void testAskPassword();
+
+ void cleanupTestCase();
+};
+
+#endif // BACKENDTEST_H
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic