Commit ee7555ae authored by Shashwat Jolly's avatar Shashwat Jolly
Browse files

Implement two-step resource configuration

Added interval auto refresh as well
parent eac06548
......@@ -5,14 +5,16 @@ kconfig_add_kcfg_files(etesyncresource_common_SRCS
set(etesyncresource_SRCS
etesyncresource.cpp
etesyncclientstate.cpp
journalsfetchjob.cpp
entriesfetchjob.cpp
etesyncclientstate.cpp
contacthandler.cpp
calendartaskbasehandler.cpp
calendarhandler.cpp
taskhandler.cpp
etesyncadapter.cpp
setupwizard.cpp
${etesyncresource_common_SRCS}
)
......@@ -46,6 +48,8 @@ target_link_libraries(akonadi_etesync_resource
KF5::Contacts
KF5::CalendarCore
KF5::KIOCore
KF5::ConfigWidgets
KF5::WindowSystem
KF5::I18n
)
......
......@@ -21,7 +21,6 @@
EteSyncClientState::EteSyncClientState()
{
init();
}
EteSyncClientState::~EteSyncClientState()
......@@ -44,6 +43,7 @@ void EteSyncClientState::init()
// mEncryptionPassword = QStringLiteral("etesync");
if (mServerUrl.isEmpty() || mUsername.isEmpty() || mPassword.isEmpty() || mEncryptionPassword.isEmpty()) {
Q_EMIT clientInitialised(false);
return;
}
......@@ -73,3 +73,53 @@ void EteSyncClientState::init()
Q_EMIT clientInitialised(true);
}
bool EteSyncClientState::initToken(QString &serverUrl, QString &username, QString &password)
{
mServerUrl = serverUrl;
mUsername = username;
mPassword = password;
// Initialise EteSync client state
mClient = EteSyncPtr(etesync_new(QStringLiteral("Akonadi EteSync Resource"), mServerUrl));
mToken = etesync_auth_get_token(mClient.get(), mUsername, mPassword);
if (mToken.isEmpty()) {
qCDebug(ETESYNC_LOG) << "Empty token";
return false;
}
qCDebug(ETESYNC_LOG) << "Received token" << mToken;
etesync_set_auth_token(mClient.get(), mToken);
return true;
}
bool EteSyncClientState::initKeypair(const QString &encryptionPassword)
{
mEncryptionPassword = encryptionPassword;
mJournalManager = EteSyncJournalManagerPtr(etesync_journal_manager_new(mClient.get()));
mDerived = etesync_crypto_derive_key(mClient.get(), mUsername, mEncryptionPassword);
// Get user keypair
EteSyncUserInfoManagerPtr userInfoManager(etesync_user_info_manager_new(mClient.get()));
EteSyncUserInfoPtr userInfo(etesync_user_info_manager_fetch(userInfoManager.get(), mUsername));
if (!userInfo) {
qCWarning(ETESYNC_LOG) << "User info obtained from server is NULL";
return false;
}
EteSyncCryptoManagerPtr userInfoCryptoManager(etesync_user_info_get_crypto_manager(userInfo.get(), mDerived));
mKeypair = EteSyncAsymmetricKeyPairPtr(etesync_user_info_get_keypair(userInfo.get(), userInfoCryptoManager.get()));
if (!mKeypair) {
qCDebug(ETESYNC_LOG) << "Empty keypair";
return false;
}
qCDebug(ETESYNC_LOG) << "Received keypair";
return true;
}
void EteSyncClientState::saveCredentials()
{
Settings::self()->setBaseUrl(mServerUrl);
Settings::self()->setUsername(mUsername);
Settings::self()->setPassword(mPassword);
Settings::self()->setEncryptionPassword(mEncryptionPassword);
Settings::self()->save();
}
......@@ -29,6 +29,9 @@ public:
~EteSyncClientState();
void init();
bool initToken(QString &serverUrl, QString &username, QString &password);
bool initKeypair(const QString &encryptionPassword);
void saveCredentials();
EteSync *client()
{
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EteSyncConfigWidget</class>
<widget class="QWidget" name="ConfigWidget">
<widget class="QWidget" name="EteSyncConfigWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>380</width>
<height>180</height>
<width>401</width>
<height>484</height>
</rect>
</property>
<property name="windowTitle">
<string>Configuration</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Configuration</string>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="checkable">
<bool>false</bool>
<property name="title">
<string>Account</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_BaseUrl">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="loginStatusLbl">
<property name="text">
<string>Login status: unknown</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="loginBtn">
<property name="text">
<string>Server URL:</string>
<string>Login with Facebook</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="kcfg_BaseUrl">
<property name="toolTip">
<string>The URL of the EteSync server</string>
<item>
<widget class="QPushButton" name="logoutBtn">
<property name="text">
<string>Logout</string>
</property>
<property name="whatsThis">
<string>The URL of the EteSync server</string>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Reminders</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="attendingReminderChkBox">
<property name="text">
<string>Show reminders for events I'm attending</string>
</property>
<property name="placeholderText">
<string notr="true">https://api.etesync.com</string>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_Username">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<item>
<widget class="QCheckBox" name="maybeAttendingReminderChkBox">
<property name="text">
<string>Username:</string>
<string>Show reminders for events I may be attending</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="kcfg_Username">
<property name="toolTip">
<string>The username that is used to log into the EteSync server</string>
<item>
<widget class="QCheckBox" name="notAttendingReminderChkBox">
<property name="text">
<string>Show reminders for events I'm not attending</string>
</property>
<property name="whatsThis">
<string>The username that is used to log into the EteSync server</string>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_Password">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<item>
<widget class="QCheckBox" name="notRespondedReminderChkBox">
<property name="text">
<string>Password:</string>
<string>Show reminders for events I have not responded to</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="kcfg_Password">
<property name="toolTip">
<string>The password that is used to log into the EteSync server</string>
</property>
<property name="whatsThis">
<string>The password that is used to log into the EteSync server</string>
<item>
<widget class="QCheckBox" name="birthdayReminderChkBox">
<property name="text">
<string>Show reminders for friends' birthdays</string>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_EncryptionPassword">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>120</width>
<height>0</height>
<width>20</width>
<height>10</height>
</size>
</property>
<property name="text">
<string>Encryption Password:</string>
</property>
</widget>
</spacer>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="kcfg_EncryptionPassword">
<property name="toolTip">
<string>Encryption password for your EteSync account</string>
</property>
<property name="whatsThis">
<string>Encryption password for your EteSync account</string>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Show event reminders</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="eventReminderHoursSpinBox">
<property name="suffix">
<string/>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string>hour(s) before</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Show birthday reminders</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="birthdayReminderDaysSpinBox"/>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_6">
<property name="text">
<string>day(s) before</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</widget>
</spacer>
</item>
</layout>
</widget>
......
......@@ -17,6 +17,9 @@
#include "etesyncresource.h"
#include <kwindowsystem.h>
#include <AkonadiCore/CachePolicy>
#include <AkonadiCore/ChangeRecorder>
#include <AkonadiCore/CollectionColorAttribute>
#include <AkonadiCore/CollectionFetchScope>
......@@ -35,6 +38,7 @@
#include "journalsfetchjob.h"
#include "settings.h"
#include "settingsadaptor.h"
#include "setupwizard.h"
using namespace EteSyncAPI;
using namespace Akonadi;
......@@ -64,6 +68,8 @@ EteSyncResource::EteSyncResource(const QString &id)
initialiseDirectory(baseDirectoryPath());
mClientState = new EteSyncClientState();
connect(mClientState, &EteSyncClientState::clientInitialised, this, &EteSyncResource::initialiseDone);
mClientState->init();
mContactHandler = ContactHandler::Ptr(new ContactHandler(this));
mCalendarHandler = CalendarHandler::Ptr(new CalendarHandler(this));
......@@ -78,16 +84,40 @@ EteSyncResource::~EteSyncResource()
{
}
void EteSyncResource::configure(WId windowId)
{
SetupWizard wizard(mClientState);
if (windowId) {
wizard.setAttribute(Qt::WA_NativeWindow, true);
KWindowSystem::setMainWindow(wizard.windowHandle(), windowId);
}
const int result = wizard.exec();
if (result == QDialog::Accepted) {
synchronize();
Q_EMIT configurationDialogAccepted();
} else {
Q_EMIT configurationDialogRejected();
}
}
void EteSyncResource::retrieveCollections()
{
// Set up root collection for resource
mResourceCollection = Collection();
mResourceCollection.setContentMimeTypes({Collection::mimeType(), Collection::virtualMimeType()});
mResourceCollection.setContentMimeTypes({Collection::mimeType()});
mResourceCollection.setName(mClientState->username());
mResourceCollection.setRemoteId(ROOT_COLLECTION_REMOTEID);
mResourceCollection.setParentCollection(Collection::root());
mResourceCollection.setRights(Collection::CanCreateCollection);
Akonadi::CachePolicy cachePolicy;
cachePolicy.setInheritFromParent(false);
cachePolicy.setSyncOnDemand(false);
cachePolicy.setCacheTimeout(-1);
cachePolicy.setIntervalCheckTime(5);
mResourceCollection.setCachePolicy(cachePolicy);
EntityDisplayAttribute *attr = mResourceCollection.attribute<EntityDisplayAttribute>(Collection::AddIfMissing);
attr->setDisplayName(mClientState->username());
attr->setIconName(QStringLiteral("akonadi-etesync"));
......@@ -197,14 +227,15 @@ void EteSyncResource::aboutToQuit()
void EteSyncResource::onReloadConfiguration()
{
qCDebug(ETESYNC_LOG) << "Resource config reload";
synchronize();
}
connect(mClientState, &EteSyncClientState::clientInitialised, this, [this](bool successful) {
qCDebug(ETESYNC_LOG) << "Resource intialised";
if (successful) {
synchronize();
}
});
mClientState->init();
void EteSyncResource::initialiseDone(bool successful)
{
qCDebug(ETESYNC_LOG) << "Resource intialised";
if (successful) {
synchronize();
}
}
QString EteSyncResource::baseDirectoryPath() const
......
......@@ -40,7 +40,7 @@ public:
Q_SIGNALS:
void initialiseDone(bool successful);
void clientInitialised(bool successful);
protected Q_SLOTS:
void retrieveCollections() override;
......@@ -54,6 +54,8 @@ protected Q_SLOTS:
void collectionChanged(const Akonadi::Collection &collection);
void collectionRemoved(const Akonadi::Collection &collection);
void configure(WId windowId) override;
protected:
void aboutToQuit() override;
......@@ -73,6 +75,7 @@ protected:
private Q_SLOTS:
void onReloadConfiguration();
void initialiseDone(bool successful);
void slotItemsRetrieved(KJob *job);
private:
......
......@@ -38,7 +38,7 @@ void JournalsFetchJob::fetchJournals()
EteSyncJournalManager *journalManager = etesync_journal_manager_new(mClient);
mJournals = etesync_journal_manager_list(journalManager);
if (!mJournals) {
setError(UserDefinedError);
setError(int(etesync_get_error_code()));
CharPtr err(etesync_get_error_message());
setErrorText(QStringFromCharPtr(err));
}
......
/*
Copyright (c) 2010 Tobias Koenig <tokoe@kde.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) any later version.
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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "setupwizard.h"
#include <KLocalizedString>
#include <KPasswordLineEdit>
#include <QFormLayout>
#include <QIcon>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include "etesync_debug.h"
SetupWizard::SetupWizard(EteSyncClientState *clientState, QWidget *parent)
: QWizard(parent), mClientState(clientState)
{
setWindowTitle(i18nc("@title:window", "EteSync configuration wizard"));
setWindowIcon(QIcon::fromTheme(QStringLiteral("akonadi-etesync")));
setPage(W_LoginPage, new LoginPage);
setPage(W_EncryptionPasswordPage, new EncryptionPasswordPage);
}
LoginPage::LoginPage(QWidget *parent)
: QWizardPage(parent)
{
setTitle(i18n("Login Credentials"));
setSubTitle(i18n("Enter your credentials to login to the EteSync server"));
QFormLayout *layout = new QFormLayout(this);
mLoginLabel = new QLabel;
layout->addWidget(mLoginLabel);
mUserName = new QLineEdit;
layout->addRow(i18n("User:"), mUserName);
registerField(QStringLiteral("credentialsUserName*"), mUserName);
mPassword = new KPasswordLineEdit;
layout->addRow(i18n("Password:"), mPassword);
registerField(QStringLiteral("credentialsPassword*"), mPassword, "password", SIGNAL(passwordChanged(QString)));
}