1 //
2 // Created by michaelpollind on 3/13/17.
3 //
4 #include "o0keychainstore.h"
5 
6 #include <QDebug>
7 #include <keychain.h>
8 #include <QDataStream>
9 #include <QBuffer>
10 #include <QEventLoop>
11 
12 using namespace QKeychain;
13 
o0keyChainStore(const QString & app,const QString & name,QObject * parent)14 o0keyChainStore::o0keyChainStore(const QString& app,const QString& name,QObject *parent):
15     O0AbstractStore(parent), app_(app),name_(name),pairs_()
16 {
17 }
18 
value(const QString & key,const QString & defaultValue)19 QString o0keyChainStore::value(const QString &key, const QString &defaultValue) {
20     return pairs_.value(key, defaultValue);
21 }
22 
setValue(const QString & key,const QString & value)23 void o0keyChainStore::setValue(const QString &key, const QString &value) {
24     pairs_.insert(key,value);
25 }
26 
persist()27 int o0keyChainStore::persist() {
28     WritePasswordJob job(app_);
29     initJob(job);
30 
31     QByteArray data;
32     QDataStream ds(&data,QIODevice::ReadWrite);
33     ds << pairs_;
34     job.setBinaryData(data);
35 
36     return executeJob(job, "persist");
37 }
38 
fetchFromKeychain()39 int o0keyChainStore::fetchFromKeychain() {
40     ReadPasswordJob job(app_);
41     initJob(job);
42     const int result = executeJob(job, "fetch");
43     if (result == 0) { // success
44         QByteArray data;
45         data.append(job.binaryData());
46         QDataStream ds(&data, QIODevice::ReadOnly);
47         ds >> pairs_;
48     }
49     return result;
50 }
51 
clearFromKeychain()52 int o0keyChainStore::clearFromKeychain() {
53     DeletePasswordJob job(app_);
54     initJob(job);
55     return executeJob(job, "clear");
56 }
57 
isEntryNotFoundError(int errorCode)58 bool o0keyChainStore::isEntryNotFoundError(int errorCode) {
59     return errorCode == QKeychain::EntryNotFound;
60 }
61 
initJob(QKeychain::Job & job) const62 void o0keyChainStore::initJob(QKeychain::Job &job) const {
63     job.setAutoDelete(false);
64     job.setKey(name_);
65 }
66 
executeJob(QKeychain::Job & job,const char * actionName) const67 int o0keyChainStore::executeJob(QKeychain::Job &job, const char *actionName) const {
68     QEventLoop loop;
69     job.connect( &job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()) );
70     job.start();
71     loop.exec();
72 
73     const QKeychain::Error errorCode = job.error();
74     if (errorCode != QKeychain::NoError) {
75         qWarning() << "keychain store could not" << actionName << name_ << ":"
76                    << job.errorString() << "(" << errorCode << ").";
77     }
78     return errorCode;
79 }
80