summaryrefslogtreecommitdiffstats
path: root/framework/src/domain/settings/accountsettings.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/domain/settings/accountsettings.cpp')
-rw-r--r--framework/src/domain/settings/accountsettings.cpp391
1 files changed, 391 insertions, 0 deletions
diff --git a/framework/src/domain/settings/accountsettings.cpp b/framework/src/domain/settings/accountsettings.cpp
new file mode 100644
index 00000000..d1019e1f
--- /dev/null
+++ b/framework/src/domain/settings/accountsettings.cpp
@@ -0,0 +1,391 @@
1/*
2 Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com>
3
4 This library is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This library is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18*/
19#include "accountsettings.h"
20
21#include <sink/store.h>
22#include <sink/log.h>
23#include <QDebug>
24#include <QDir>
25#include <QUrl>
26
27using namespace Sink;
28using namespace Sink::ApplicationDomain;
29
30SINK_DEBUG_AREA("accountsettings")
31
32AccountSettings::AccountSettings(QObject *parent)
33 : QObject(parent)
34{
35}
36
37void AccountSettings::setAccountType(const QByteArray &type)
38{
39 mAccountType = type;
40}
41
42QByteArray AccountSettings::accountType() const
43{
44 return mAccountType;
45}
46
47void AccountSettings::setAccountIdentifier(const QByteArray &id)
48{
49 if (id.isEmpty()) {
50 return;
51 }
52 mAccountIdentifier = id;
53
54 //Clear
55 mIcon = QString();
56 mName = QString();
57 mImapServer = QString();
58 mImapUsername = QString();
59 mImapPassword = QString();
60 mSmtpServer = QString();
61 mSmtpUsername = QString();
62 mSmtpPassword = QString();
63 mCardDavServer = QString();
64 mCardDavUsername = QString();
65 mCardDavPassword = QString();
66 emit changed();
67 emit imapResourceChanged();
68 emit smtpResourceChanged();
69 emit cardDavResourceChanged();
70
71 load();
72
73}
74
75QByteArray AccountSettings::accountIdentifier() const
76{
77 return mAccountIdentifier;
78}
79
80void AccountSettings::setPath(const QUrl &path)
81{
82 auto normalizedPath = path.path();
83 if (mPath != normalizedPath) {
84 mPath = normalizedPath;
85 emit pathChanged();
86 }
87}
88
89QUrl AccountSettings::path() const
90{
91 return QUrl(mPath);
92}
93
94QValidator *AccountSettings::pathValidator() const
95{
96 class PathValidator : public QValidator {
97 State validate(QString &input, int &pos) const {
98 Q_UNUSED(pos);
99 if (!input.isEmpty() && QDir(input).exists()) {
100 return Acceptable;
101 } else {
102 return Intermediate;
103 }
104 }
105 };
106 static PathValidator *pathValidator = new PathValidator;
107 return pathValidator;
108}
109
110QValidator *AccountSettings::imapServerValidator() const
111{
112 class ImapServerValidator : public QValidator {
113 State validate(QString &input, int &pos) const {
114 Q_UNUSED(pos);
115 // imaps://mainserver.example.net:475
116 const QUrl url(input);
117 static QSet<QString> validProtocols = QSet<QString>() << "imap" << "imaps";
118 if (url.isValid() && validProtocols.contains(url.scheme().toLower())) {
119 return Acceptable;
120 } else {
121 return Intermediate;
122 }
123 }
124 };
125 static ImapServerValidator *validator = new ImapServerValidator;
126 return validator;
127}
128
129QValidator *AccountSettings::smtpServerValidator() const
130{
131 class SmtpServerValidator : public QValidator {
132 State validate(QString &input, int &pos) const {
133 Q_UNUSED(pos);
134 // smtps://mainserver.example.net:475
135 const QUrl url(input);
136 static QSet<QString> validProtocols = QSet<QString>() << "smtp" << "smtps";
137 if (url.isValid() && validProtocols.contains(url.scheme().toLower())) {
138 return Acceptable;
139 } else {
140 return Intermediate;
141 }
142 }
143 };
144 static SmtpServerValidator *validator = new SmtpServerValidator;
145 return validator;
146}
147
148void AccountSettings::saveAccount()
149{
150 if (mAccountIdentifier.isEmpty()) {
151 auto account = ApplicationDomainType::createEntity<SinkAccount>();
152 mAccountIdentifier = account.identifier();
153 Q_ASSERT(!mAccountType.isEmpty());
154 account.setAccountType(mAccountType);
155 account.setName(mName);
156 account.setIcon(mIcon);
157 Store::create(account)
158 .onError([](const KAsync::Error &error) {
159 qWarning() << "Error while creating account: " << error.errorMessage;;
160 })
161 .exec();
162 } else {
163 qDebug() << "Saving account " << mAccountIdentifier << mMailtransportIdentifier;
164 Q_ASSERT(!mAccountIdentifier.isEmpty());
165 SinkAccount account(mAccountIdentifier);
166 account.setAccountType(mAccountType);
167 account.setName(mName);
168 account.setIcon(mIcon);
169 Q_ASSERT(!account.identifier().isEmpty());
170 Store::modify(account)
171 .onError([](const KAsync::Error &error) {
172 qWarning() << "Error while creating account: " << error.errorMessage;;
173 })
174 .exec();
175 }
176}
177
178void AccountSettings::loadAccount()
179{
180 Q_ASSERT(!mAccountIdentifier.isEmpty());
181 Store::fetchOne<SinkAccount>(Query().filter(mAccountIdentifier).request<SinkAccount::Icon>().request<SinkAccount::Name>().request<SinkAccount::AccountType>())
182 .then([this](const SinkAccount &account) {
183 mAccountType = account.getAccountType().toLatin1();
184 mIcon = account.getIcon();
185 mName = account.getName();
186 emit changed();
187 }).exec();
188}
189
190void AccountSettings::loadImapResource()
191{
192 Store::fetchOne<SinkResource>(Query().filter<SinkResource::Account>(mAccountIdentifier).containsFilter<SinkResource::Capabilities>(ResourceCapabilities::Mail::storage))
193 .then([this](const SinkResource &resource) {
194 mImapIdentifier = resource.identifier();
195 mImapServer = resource.getProperty("server").toString();
196 mImapUsername = resource.getProperty("username").toString();
197 mImapPassword = resource.getProperty("password").toString();
198 emit imapResourceChanged();
199 }).onError([](const KAsync::Error &error) {
200 qWarning() << "Failed to find the imap resource: " << error.errorMessage;
201 }).exec();
202}
203
204void AccountSettings::loadMaildirResource()
205{
206 Store::fetchOne<SinkResource>(Query().filter<SinkResource::Account>(mAccountIdentifier).containsFilter<SinkResource::Capabilities>(ResourceCapabilities::Mail::storage))
207 .then([this](const SinkResource &resource) {
208 mMaildirIdentifier = resource.identifier();
209 auto path = resource.getProperty("path").toString();
210 if (mPath != path) {
211 mPath = path;
212 emit pathChanged();
213 }
214 }).onError([](const KAsync::Error &error) {
215 SinkWarning() << "Failed to find the maildir resource: " << error.errorMessage;
216 }).exec();
217}
218
219void AccountSettings::loadMailtransportResource()
220{
221 Store::fetchOne<SinkResource>(Query().filter<SinkResource::Account>(mAccountIdentifier).containsFilter<SinkResource::Capabilities>(ResourceCapabilities::Mail::transport))
222 .then([this](const SinkResource &resource) {
223 mMailtransportIdentifier = resource.identifier();
224 mSmtpServer = resource.getProperty("server").toString();
225 mSmtpUsername = resource.getProperty("username").toString();
226 mSmtpPassword = resource.getProperty("password").toString();
227 emit smtpResourceChanged();
228 }).onError([](const KAsync::Error &error) {
229 SinkWarning() << "Failed to find the smtp resource: " << error.errorMessage;
230 }).exec();
231}
232
233void AccountSettings::loadIdentity()
234{
235 //FIXME this assumes that we only ever have one identity per account
236 Store::fetchOne<Identity>(Query().filter<Identity::Account>(mAccountIdentifier))
237 .then([this](const Identity &identity) {
238 mIdentityIdentifier = identity.identifier();
239 mUsername = identity.getName();
240 mEmailAddress = identity.getAddress();
241 emit identityChanged();
242 }).onError([](const KAsync::Error &error) {
243 SinkWarning() << "Failed to find the identity resource: " << error.errorMessage;
244 }).exec();
245}
246
247void AccountSettings::loadCardDavResource()
248{
249 Store::fetchOne<SinkResource>(Query().filter<SinkResource::Account>(mAccountIdentifier).containsFilter<SinkResource::Capabilities>(ResourceCapabilities::Mail::storage))
250 .then([this](const SinkResource &resource) {
251 mCardDavIdentifier = resource.identifier();
252 mCardDavServer = resource.getProperty("server").toString();
253 mCardDavUsername = resource.getProperty("username").toString();
254 mCardDavPassword = resource.getProperty("password").toString();
255 emit cardDavResourceChanged();
256 }).onError([](const KAsync::Error &error) {
257 qWarning() << "Failed to find the CardDAV resource: " << error.errorMessage;
258 }).exec();
259}
260
261
262template<typename ResourceType>
263static QByteArray saveResource(const QByteArray &accountIdentifier, const QByteArray &identifier, const std::map<QByteArray, QVariant> &properties)
264{
265 if (!identifier.isEmpty()) {
266 SinkResource resource(identifier);
267 for (const auto &pair : properties) {
268 resource.setProperty(pair.first, pair.second);
269 }
270 Store::modify(resource)
271 .onError([](const KAsync::Error &error) {
272 SinkWarning() << "Error while modifying resource: " << error.errorMessage;
273 })
274 .exec();
275 } else {
276 auto resource = ResourceType::create(accountIdentifier);
277 auto newIdentifier = resource.identifier();
278 for (const auto &pair : properties) {
279 resource.setProperty(pair.first, pair.second);
280 }
281 Store::create(resource)
282 .onError([](const KAsync::Error &error) {
283 SinkWarning() << "Error while creating resource: " << error.errorMessage;
284 })
285 .exec();
286 return newIdentifier;
287 }
288 return identifier;
289}
290
291void AccountSettings::saveImapResource()
292{
293 mImapIdentifier = saveResource<ImapResource>(mAccountIdentifier, mImapIdentifier, {
294 {"server", mImapServer},
295 {"username", mImapUsername},
296 {"password", mImapPassword},
297 });
298}
299
300void AccountSettings::saveCardDavResource()
301{
302 mCardDavIdentifier = saveResource<CardDavResource>(mAccountIdentifier, mCardDavIdentifier, {
303 {"server", mCardDavServer},
304 {"username", mCardDavUsername},
305 {"password", mCardDavPassword},
306 });
307}
308
309void AccountSettings::saveMaildirResource()
310{
311 mMaildirIdentifier = saveResource<MaildirResource>(mAccountIdentifier, mMaildirIdentifier, {
312 {"path", mPath},
313 });
314}
315
316void AccountSettings::saveMailtransportResource()
317{
318 mMailtransportIdentifier = saveResource<MailtransportResource>(mAccountIdentifier, mMailtransportIdentifier, {
319 {"server", mSmtpServer},
320 {"username", mSmtpUsername},
321 {"password", mSmtpPassword},
322 });
323}
324
325void AccountSettings::saveIdentity()
326{
327 if (!mIdentityIdentifier.isEmpty()) {
328 Identity identity(mMailtransportIdentifier);
329 identity.setName(mUsername);
330 identity.setAddress(mEmailAddress);
331 Store::modify(identity)
332 .onError([](const KAsync::Error &error) {
333 SinkWarning() << "Error while modifying identity: " << error.errorMessage;
334 })
335 .exec();
336 } else {
337 auto identity = ApplicationDomainType::createEntity<Identity>();
338 mIdentityIdentifier = identity.identifier();
339 identity.setAccount(mAccountIdentifier);
340 identity.setName(mUsername);
341 identity.setAddress(mEmailAddress);
342 Store::create(identity)
343 .onError([](const KAsync::Error &error) {
344 SinkWarning() << "Error while creating identity: " << error.errorMessage;
345 })
346 .exec();
347 }
348}
349
350void AccountSettings::removeResource(const QByteArray &identifier)
351{
352 if (identifier.isEmpty()) {
353 SinkWarning() << "We're missing an identifier";
354 } else {
355 SinkResource resource(identifier);
356 Store::remove(resource)
357 .onError([](const KAsync::Error &error) {
358 SinkWarning() << "Error while removing resource: " << error.errorMessage;
359 })
360 .exec();
361 }
362}
363
364void AccountSettings::removeAccount()
365{
366 if (mAccountIdentifier.isEmpty()) {
367 SinkWarning() << "We're missing an identifier";
368 } else {
369 SinkAccount account(mAccountIdentifier);
370 Store::remove(account)
371 .onError([](const KAsync::Error &error) {
372 SinkWarning() << "Error while removing account: " << error.errorMessage;
373 })
374 .exec();
375 }
376}
377
378void AccountSettings::removeIdentity()
379{
380 if (mIdentityIdentifier.isEmpty()) {
381 SinkWarning() << "We're missing an identifier";
382 } else {
383 Identity identity(mIdentityIdentifier);
384 Store::remove(identity)
385 .onError([](const KAsync::Error &error) {
386 SinkWarning() << "Error while removing identity: " << error.errorMessage;
387 })
388 .exec();
389 }
390}
391