From 5c3a04b72d3e169ca67ec45635893bb1f3b54585 Mon Sep 17 00:00:00 2001
From: Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>
Date: Fri, 24 Apr 2015 17:56:04 -0400
Subject: [PATCH] certificate: Begin to support remote certificates

Refs #68196
---
 src/account.cpp                           |  39 ++++++++-
 src/account.h                             |  24 ++---
 src/certificate.cpp                       |  73 +++++++++++++---
 src/certificate.h                         |  20 ++++-
 src/certificatemodel.cpp                  | 102 ++++++++++++----------
 src/certificatemodel.h                    |   9 +-
 src/daemoncertificatecollection.cpp       |  29 ++++--
 src/daemoncertificatecollection.h         |   1 +
 src/private/account_p.h                   |  24 +++--
 src/private/certificatemodel_p.h          |  66 ++++++++++++++
 src/qtwrapper/configurationmanager_wrap.h |   4 +-
 11 files changed, 298 insertions(+), 93 deletions(-)
 create mode 100644 src/private/certificatemodel_p.h

diff --git a/src/account.cpp b/src/account.cpp
index d29cebd2..61427fdc 100644
--- a/src/account.cpp
+++ b/src/account.cpp
@@ -36,6 +36,7 @@
 #include "certificate.h"
 #include "certificatemodel.h"
 #include "accountmodel.h"
+#include "private/certificatemodel_p.h"
 #include "private/account_p.h"
 #include "private/accountmodel_p.h"
 #include "credentialmodel.h"
@@ -67,6 +68,10 @@ const account_function AccountPrivate::stateMachineActionsOnState[6][7] = {
 };
 #undef AP
 
+//Host the current highest interal identifier. The internal id is used for some bitmasks
+//when objects have a different status for each account
+static uint p_sAutoIncrementId = 0;
+
 AccountPrivate::AccountPrivate(Account* acc) : QObject(acc),q_ptr(acc),m_pCredentials(nullptr),m_pCodecModel(nullptr),
 m_LastErrorCode(-1),m_VoiceMailCount(0),m_pRingToneModel(nullptr),
 m_CurrentState(Account::EditState::READY),
@@ -74,7 +79,8 @@ m_pAccountNumber(nullptr),m_pKeyExchangeModel(nullptr),m_pSecurityEvaluationMode
 m_pCaCert(nullptr),m_pTlsCert(nullptr),m_pPrivateKey(nullptr),m_isLoaded(true),m_pCipherModel(nullptr),
 m_pStatusModel(nullptr),m_LastTransportCode(0),m_RegistrationState(Account::RegistrationState::UNREGISTERED),
 m_UseDefaultPort(false),m_pProtocolModel(nullptr),m_pBootstrapModel(nullptr),m_RemoteEnabledState(false),
-m_HaveCalled(false),m_TotalCount(0),m_LastWeekCount(0),m_LastTrimCount(0),m_LastUsed(0)
+m_HaveCalled(false),m_TotalCount(0),m_LastWeekCount(0),m_LastTrimCount(0),m_LastUsed(0),m_pKnownCertificates(nullptr),
+m_pBlacklistedCertificates(nullptr), m_pTrustedCertificates(nullptr),m_InternalId(++p_sAutoIncrementId)
 {
    Q_Q(Account);
 }
@@ -432,6 +438,33 @@ BootstrapModel* Account::bootstrapModel() const
    return d_ptr->m_pBootstrapModel;
 }
 
+QAbstractItemModel* Account::knownCertificateModel() const
+{
+   if (!d_ptr->m_pKnownCertificates) {
+      d_ptr->m_pKnownCertificates = CertificateModel::instance()->d_ptr->createKnownList(this);
+   }
+
+   return d_ptr->m_pKnownCertificates;
+}
+
+QAbstractItemModel* Account::backlistedCertificatesModel() const
+{
+   if (!d_ptr->m_pBlacklistedCertificates) {
+      d_ptr->m_pBlacklistedCertificates = CertificateModel::instance()->d_ptr->createBlockList(this);
+   }
+
+   return d_ptr->m_pBlacklistedCertificates;
+}
+
+QAbstractItemModel* Account::trustedCertificatesModel() const
+{
+   if (!d_ptr->m_pTrustedCertificates) {
+      d_ptr->m_pTrustedCertificates = CertificateModel::instance()->d_ptr->createTrustList(this);
+   }
+
+   return d_ptr->m_pTrustedCertificates;
+}
+
 bool Account::isUsedForOutgogingCall() const
 {
    return d_ptr->m_HaveCalled;
@@ -1023,6 +1056,10 @@ bool Account::supportScheme( URI::SchemeType type )
    return false;
 }
 
+uint AccountPrivate::internalId() const
+{
+   return m_InternalId;
+}
 
 /*****************************************************************************
  *                                                                           *
diff --git a/src/account.h b/src/account.h
index e84af502..405ef6b9 100644
--- a/src/account.h
+++ b/src/account.h
@@ -82,6 +82,7 @@ class LIB_EXPORT Account : public QObject {
    friend class TlsMethodModel;
    friend class BootstrapModelPrivate;
    friend class ContactMethod;
+   friend class Certificate;
 
    //Properties
    Q_PROPERTY(QByteArray     id                           READ id                                                                 )
@@ -259,16 +260,19 @@ class LIB_EXPORT Account : public QObject {
       QVariant         stateColor      () const;
       virtual bool     isLoaded        () const;
 
-      Q_INVOKABLE CredentialModel*         credentialModel        () const;
-      Q_INVOKABLE CodecModel*              codecModel             () const;
-      Q_INVOKABLE RingToneModel*           ringToneModel          () const;
-      Q_INVOKABLE KeyExchangeModel*        keyExchangeModel       () const;
-      Q_INVOKABLE CipherModel*             cipherModel            () const;
-      Q_INVOKABLE AccountStatusModel*      statusModel            () const;
-      Q_INVOKABLE SecurityEvaluationModel* securityEvaluationModel() const;
-      Q_INVOKABLE TlsMethodModel*          tlsMethodModel         () const;
-      Q_INVOKABLE ProtocolModel*           protocolModel          () const;
-      Q_INVOKABLE BootstrapModel*          bootstrapModel         () const;
+      Q_INVOKABLE CredentialModel*         credentialModel            () const;
+      Q_INVOKABLE CodecModel*              codecModel                 () const;
+      Q_INVOKABLE RingToneModel*           ringToneModel              () const;
+      Q_INVOKABLE KeyExchangeModel*        keyExchangeModel           () const;
+      Q_INVOKABLE CipherModel*             cipherModel                () const;
+      Q_INVOKABLE AccountStatusModel*      statusModel                () const;
+      Q_INVOKABLE SecurityEvaluationModel* securityEvaluationModel    () const;
+      Q_INVOKABLE TlsMethodModel*          tlsMethodModel             () const;
+      Q_INVOKABLE ProtocolModel*           protocolModel              () const;
+      Q_INVOKABLE BootstrapModel*          bootstrapModel             () const;
+      Q_INVOKABLE QAbstractItemModel*      knownCertificateModel      () const;
+      Q_INVOKABLE QAbstractItemModel*      backlistedCertificatesModel() const;
+      Q_INVOKABLE QAbstractItemModel*      trustedCertificatesModel   () const;
 
       //Getters
       QString hostname                     () const;
diff --git a/src/certificate.cpp b/src/certificate.cpp
index 199a3912..7e97eb8c 100644
--- a/src/certificate.cpp
+++ b/src/certificate.cpp
@@ -21,6 +21,9 @@
 #include <QtCore/QFile>
 #include <QtCore/QDateTime>
 
+//STD
+#include <stdint.h>
+
 //Ring daemon
 #include <security_const.h>
 
@@ -28,6 +31,9 @@
 #include "dbus/configurationmanager.h"
 #include <certificatemodel.h>
 #include "private/matrixutils.h"
+#include "private/account_p.h"
+#include "private/certificatemodel_p.h"
+#include <account.h>
 
 class DetailsCache {
 public:
@@ -102,11 +108,12 @@ public:
    ~CertificatePrivate();
 
    //Attributes
-   QUrl              m_Path       ;
-   Certificate::Type m_Type       ;
-   QByteArray        m_Content    ;
-   LoadingType       m_LoadingType;
-   QByteArray        m_Id         ;
+   QUrl              m_Path        ;
+   Certificate::Type m_Type        ;
+   QByteArray        m_Content     ;
+   LoadingType       m_LoadingType ;
+   QByteArray        m_Id          ;
+   quint64           m_Statuses [3];
 
    mutable DetailsCache* m_pDetailsCache;
    mutable ChecksCache*  m_pCheckCache  ;
@@ -217,7 +224,7 @@ Matrix1D<Certificate::Details,QString> CertificatePrivate::m_slDetailssDescripti
 
 
 CertificatePrivate::CertificatePrivate(LoadingType _type) :
-m_pCheckCache(nullptr), m_pDetailsCache(nullptr), m_LoadingType(_type)
+m_pCheckCache(nullptr), m_pDetailsCache(nullptr), m_LoadingType(_type),m_Statuses{0,0,0}
 {
 }
 
@@ -630,7 +637,6 @@ bool Certificate::isActivated() const {
    return d_ptr->m_pCheckCache->m_NotActivated == Certificate::CheckValues::PASSED;
 }
 
-
 void Certificate::setPath(const QUrl& path)
 {
    d_ptr->m_Path = path;
@@ -718,16 +724,63 @@ QVariant Certificate::detailResult(Certificate::Details detail) const
  */
 QAbstractItemModel* Certificate::model() const
 {
-   return CertificateModel::instance()->model(this);
+   return CertificateModel::instance()->d_ptr->model(this);
 }
 
 /**
- * This model furter reduce the data to only return the relevant certificate
+ * This model further reduce the data to only return the relevant certificate
  * checks.
  */
 QAbstractItemModel* Certificate::checksModel() const
 {
-   return CertificateModel::instance()->checksModel(this);
+   return CertificateModel::instance()->d_ptr->checksModel(this);
+}
+
+bool Certificate::setStatus(const Account* a, Status s)
+{
+   if (!a)
+      return false;
+
+   //This status is stored as a 3bit bitmask in 3 64bit integers
+
+   const int maskId = a->d_ptr->internalId();
+   const int position = (maskId*3)/64;
+   const int offset   = (maskId*3)%64;
+
+   //Only 63 accounts are currently supported
+   if (position > 3)
+      return false;
+
+   d_ptr->m_Statuses[position] = static_cast<int>(s) << offset;
+
+   ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
+
+   //Notify the daemon
+   if (hasRemote()) {
+      configurationManager.setCertificateStatus(a->id(),d_ptr->m_Id,CertificateModelPrivate::m_StatusMap[s]);
+   }
+   else {
+      //d_ptr->m_Id = configurationManager.pinCertificatePath(path());
+      //TODO register the certificate in the daemon
+   }
+
+   return true;
+}
+
+Certificate::Status Certificate::status(const Account* a) const
+{
+   const int maskId = a->d_ptr->internalId();
+   const int position = (maskId*3)/64;
+   const int offset   = (maskId*3)%64;
+
+   if (position >= 3)
+      return Certificate::Status::UNDEFINED;
+
+   const int raw = (d_ptr->m_Statuses[position] >> offset) & 0b111;
+
+   Q_ASSERT(raw < enum_class_size<Certificate::Status>());
+
+   return static_cast<Certificate::Status>(raw);
 }
 
 #include <certificate.moc>
diff --git a/src/certificate.h b/src/certificate.h
index 3637232f..166f81f3 100644
--- a/src/certificate.h
+++ b/src/certificate.h
@@ -26,6 +26,7 @@
 class QAbstractItemModel;
 
 class CertificatePrivate;
+class Account;
 
 /**
  * This class represent a conceptual certificate.
@@ -200,6 +201,21 @@ public:
    };
    Q_ENUMS(CheckValues)
 
+   /**
+    * A certificate local status. A single certificate can have multiple status
+    * at once depending on the context. For example, one account may block a
+    * certificate while another one trust it.
+    */
+   enum class Status {
+      UNDEFINED      ,
+      ALLOWED        ,
+      BANNED         ,
+      REVOKED        ,
+      REVOKED_ALLOWED,
+      COUNT__
+   };
+   Q_ENUMS(Status)
+
    //Getter
    QUrl path                            (                             ) const;
    Certificate::Type type               (                             ) const;
@@ -209,6 +225,7 @@ public:
    QAbstractItemModel* checksModel      (                             ) const;
    bool hasRemote                       (                             ) const;
    QByteArray remoteId                  (                             ) const;
+   Status     status                    ( const Account* a            ) const;
 
    static QString getName        (Certificate::Checks   check  );
    static QString getName        (Certificate::Details details );
@@ -258,9 +275,9 @@ public:
    QDateTime  nextExpectedUpdateDate               () const;
    QString    outgoingServer                       () const;
 
-
    //Setter
    void setPath(const QUrl& path);
+   bool setStatus(const Account* a, Status s);
 
    //Mutator
    Q_INVOKABLE bool pin();
@@ -281,5 +298,6 @@ Q_DECLARE_METATYPE(Certificate*)
 Q_DECLARE_METATYPE(Certificate::CheckValues)
 Q_DECLARE_METATYPE(Certificate::Checks)
 Q_DECLARE_METATYPE(Certificate::Details)
+Q_DECLARE_METATYPE(Certificate::Status)
 
 #endif
diff --git a/src/certificatemodel.cpp b/src/certificatemodel.cpp
index 33a75990..763d78f4 100644
--- a/src/certificatemodel.cpp
+++ b/src/certificatemodel.cpp
@@ -29,11 +29,17 @@
 //LibSTDC++
 #include <functional>
 
+//Dring
+#include "dbus/configurationmanager.h"
+#include "security_const.h"
+
 //Ring
 #include "certificate.h"
 #include "account.h"
 #include "foldercertificatecollection.h"
+#include "daemoncertificatecollection.h"
 #include "private/matrixutils.h"
+#include "private/certificatemodel_p.h"
 
 enum class DetailType : uchar
 {
@@ -42,6 +48,7 @@ enum class DetailType : uchar
    CHECK ,
 };
 
+
 struct CertificateNode {
 
    CertificateNode(int index, CertificateModel::NodeType level, CertificateNode* parent, Certificate* cert);
@@ -81,40 +88,17 @@ private:
    CertificateNode* m_pRoot;
 };
 
-class CertificateModelPrivate
-{
-public:
-   CertificateModelPrivate(CertificateModel* parent);
-   virtual ~CertificateModelPrivate();
-
-   //Helper
-   CertificateNode* defaultCategory();
-   CertificateNode* createCategory(const QString& name, const QString& col2, const QString& tooltip);
-   CertificateNode* createCategory(const Account* a);
-   CertificateNode* addToTree(Certificate* cert, CertificateNode* category = nullptr);
-   CertificateNode* addToTree(Certificate* cert, Account* a);
-   QModelIndex      createIndex(int r ,int c , void* p);
-   QAbstractItemModel* getModelCommon(CertificateNode* node);
-
-   //Attributes
-   QVector<CertificateNode*>        m_lTopLevelNodes   ;
-   QHash<QString,Certificate*>      m_hCertificates    ;
-   CertificateNode*                 m_pDefaultCategory ;
-   QMutex                           m_CertLoader       ;
-   QHash<const Account*,CertificateNode*> m_hAccToCat  ;
-   QHash<const QString&,CertificateNode*> m_hStrToCat  ;
-   QHash<const Certificate*,CertificateNode*> m_hNodes ;
-
-   //Singleton
-   static CertificateModel* m_spInstance;
-
-private:
-   CertificateModel* q_ptr;
-};
-
 //TODO remove
 static FolderCertificateCollection* m_pFallbackCollection = nullptr;
 
+const Matrix1D<Certificate::Status, const char*> CertificateModelPrivate::m_StatusMap = {{
+/* Certificate::Status::UNDEFINED      */ DRing::Certificate::Status::UNDEFINED,
+/* Certificate::Status::ALLOWED        */ DRing::Certificate::Status::ALLOWED  ,
+/* Certificate::Status::BANNED         */ DRing::Certificate::Status::BANNED   ,
+/* Certificate::Status::REVOKED        */ ""                                   ,
+/* Certificate::Status::REVOKED_ALLOWED*/ DRing::Certificate::Status::ALLOWED  ,
+}};
+
 CertificateModel* CertificateModelPrivate::m_spInstance = nullptr;
 
 CertificateModelPrivate::~CertificateModelPrivate()
@@ -146,6 +130,11 @@ CertificateModel::CertificateModel(QObject* parent) : QAbstractItemModel(parent)
       FolderCertificateCollection::Options::FALLBACK | FolderCertificateCollection::Options::READ_WRITE,
       QObject::tr("Local certificate store")
    );
+
+   //Load the daemon certificate store
+   DaemonCertificateCollection* dcol = addCollection<DaemonCertificateCollection>();
+   dcol->load();
+
    m_pFallbackCollection->load();
 }
 
@@ -632,39 +621,28 @@ QAbstractItemModel* CertificateModelPrivate::getModelCommon(CertificateNode* nod
    return nullptr;
 }
 
-/**
- * Create a view of the CertificateModel with only the certificates
- * associated with an account. This doesn't contain the account
- * own certificates.
- */
-QAbstractItemModel* CertificateModel::model(const Account* a ) const
-{
-   CertificateNode* cat = d_ptr->createCategory(a);
-   return new CertificateProxyModel(const_cast<CertificateModel*>(this),cat);
-}
-
 /**
  * This model is a proxy of CertificateModel with only the current certificate
  *
  * Please note that the object ownership will be transferred. To avoid memory
  * leaks, the users of this object must delete it once they are done with it.
  */
-QAbstractItemModel* CertificateModel::model(const Certificate* cert) const
+QAbstractItemModel* CertificateModelPrivate::model(const Certificate* cert) const
 {
    if (!cert)
       return nullptr;
-   return d_ptr->getModelCommon(d_ptr->m_hNodes[cert]);
+   return const_cast<CertificateModelPrivate*>(this)->getModelCommon(m_hNodes[cert]);
 }
 
 /**
  * Return the list of security checks performed on the certificate as a model
  */
-QAbstractItemModel* CertificateModel::checksModel(const Certificate* cert) const
+QAbstractItemModel* CertificateModelPrivate::checksModel(const Certificate* cert) const
 {
    if (!cert)
       return nullptr;
 
-   CertificateNode* node = d_ptr->m_hNodes[cert];
+   CertificateNode* node = m_hNodes[cert];
 
    if (!node)
       return nullptr;
@@ -675,7 +653,7 @@ QAbstractItemModel* CertificateModel::checksModel(const Certificate* cert) const
    if (node->m_lChildren.size() < 2)
       return nullptr;
 
-   return d_ptr->getModelCommon(node->m_lChildren[1]);
+   return const_cast<CertificateModelPrivate*>(this)->getModelCommon(node->m_lChildren[1]);
 }
 
 /**
@@ -686,7 +664,7 @@ QAbstractItemModel* CertificateModel::checksModel(const Certificate* cert) const
  * Please note that the object ownership will be transferred. To avoid memory
  * leaks, the users of this object must delete it once they are done with it.
  */
-QAbstractItemModel* CertificateModel::model(const QModelIndex& idx) const
+QAbstractItemModel* CertificateModel::singleCertificateModel(const QModelIndex& idx) const
 {
    if ((!idx.isValid()))
       return nullptr;
@@ -707,6 +685,34 @@ QAbstractItemModel* CertificateModel::model(const QModelIndex& idx) const
    return d_ptr->getModelCommon(node);
 }
 
+/**
+ * Create a view of the CertificateModel with only the certificates
+ * associated with an account. This doesn't contain the account
+ * own certificates.
+ */
+QAbstractItemModel* CertificateModelPrivate::createKnownList(const Account* a) const
+{
+   CertificateNode* cat = const_cast<CertificateModelPrivate*>(this)->createCategory(a);
+   return new CertificateProxyModel(const_cast<CertificateModel*>(q_ptr),cat);
+}
+
+QAbstractItemModel* CertificateModelPrivate::createBlockList(const Account* a) const
+{
+   CertificateNode* cat = const_cast<CertificateModelPrivate*>(this)->createCategory(a->id()+"block",QString(),QString());
+
+   ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
+
+//    const QStringList ids = configurationManager.setCertificateStatus(a->id(), );
+
+   return new CertificateProxyModel(const_cast<CertificateModel*>(q_ptr),cat);
+}
+
+QAbstractItemModel* CertificateModelPrivate::createTrustList(const Account* a) const
+{
+   CertificateNode* cat = const_cast<CertificateModelPrivate*>(this)->createCategory(a->id()+"trust",QString(),QString());
+   return new CertificateProxyModel(const_cast<CertificateModel*>(q_ptr),cat);
+}
+
 void CertificateModel::collectionAddedCallback(CollectionInterface* collection)
 {
    Q_UNUSED(collection)
diff --git a/src/certificatemodel.h b/src/certificatemodel.h
index d0f33887..641bc51b 100644
--- a/src/certificatemodel.h
+++ b/src/certificatemodel.h
@@ -32,6 +32,8 @@ class LIB_EXPORT CertificateModel : public QAbstractItemModel, public Collection
 public:
    friend class CertificateProxyModel;
    friend class CertificateNode;
+   friend class Certificate;
+   friend class Account;
    friend class DaemonCertificateCollectionPrivate;
 
    enum class Role {
@@ -70,11 +72,8 @@ public:
    virtual QVariant      headerData  ( int section, Qt::Orientation, int role = Qt::DisplayRole    ) const override;
    virtual QHash<int,QByteArray> roleNames() const override;
 
-   //Getters
-   QAbstractItemModel* model      (const Certificate* cert) const;
-   QAbstractItemModel* model      (const QModelIndex& idx ) const;
-   QAbstractItemModel* model      (const Account* a       ) const;
-   QAbstractItemModel* checksModel(const Certificate* cert) const;
+   //Getter
+   QAbstractItemModel* singleCertificateModel(const QModelIndex& idx) const;
 
    //Mutator
    Certificate* getCertificate(const QUrl& path, Certificate::Type type = Certificate::Type::NONE);
diff --git a/src/daemoncertificatecollection.cpp b/src/daemoncertificatecollection.cpp
index f29c85de..bf610757 100644
--- a/src/daemoncertificatecollection.cpp
+++ b/src/daemoncertificatecollection.cpp
@@ -20,6 +20,7 @@
 //Ring
 #include "certificate.h"
 #include "certificatemodel.h"
+#include "delegates/pixmapmanipulationdelegate.h"
 
 //Dring
 #include "dbus/configurationmanager.h"
@@ -52,15 +53,23 @@ public:
    DaemonCertificateCollection* q_ptr;
 
 public Q_SLOTS:
-   void slotCertificateAdded(const QString& id);
+   void slotCertificatePinned(const QString& id);
    void slotCertificateExpired(const QString& id);
+   void slotCertificatePathPinned(const QString& path, const QStringList& certIds);
 };
 
 DaemonCertificateCollectionPrivate::DaemonCertificateCollectionPrivate(DaemonCertificateCollection* parent) : QObject(), q_ptr(parent)
 {
    ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
-//   connect(&configurationManager,&ConfigurationManagerInterface::certificateAdded  ,this,&DaemonCertificateCollectionPrivate::slotCertificateAdded  );
-//   connect(&configurationManager,&ConfigurationManagerInterface::certificateExpired,this,&DaemonCertificateCollectionPrivate::slotCertificateExpired);
+
+   connect(&configurationManager, &ConfigurationManagerInterface::certificatePinned     , this, &DaemonCertificateCollectionPrivate::slotCertificatePinned    );
+
+   connect(&configurationManager, &ConfigurationManagerInterface::certificateExpired    , this, &DaemonCertificateCollectionPrivate::slotCertificateExpired   );
+
+   connect(&configurationManager, &ConfigurationManagerInterface::certificatePathPinned , this, &DaemonCertificateCollectionPrivate::slotCertificatePathPinned);
+
+   //    connect(&configurationManager, &ConfigurationManagerInterface::incomingTrustRequest  , this, &DaemonCertificateCollectionPrivate::);
+
 }
 
 DaemonCertificateCollection::DaemonCertificateCollection(CollectionMediator<Certificate>* mediator, const QString& path) :
@@ -74,7 +83,7 @@ DaemonCertificateCollection::~DaemonCertificateCollection()
    delete d_ptr;
 }
 
-void DaemonCertificateCollectionPrivate::slotCertificateAdded(const QString& id)
+void DaemonCertificateCollectionPrivate::slotCertificatePinned(const QString& id)
 {
    qDebug() << "\n\nCERTIFICATE ADDED" << id;
    Certificate* cert = CertificateModel::instance()->getCertificateFromId(id);
@@ -86,10 +95,16 @@ void DaemonCertificateCollectionPrivate::slotCertificateExpired(const QString& i
    qDebug() << "\n\nCERTIFICATE EXPIRED" << id;
 }
 
+void DaemonCertificateCollectionPrivate::slotCertificatePathPinned(const QString& path, const QStringList& certIds)
+{
+   //Create a new collection if it is a directory or size > 1
+   qDebug() << "\n\nCERTIFICATE PATH PINNING" << path << certIds;
+}
+
 bool DaemonCertificateCollection::load()
 {
-//   ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
-//   qDebug() << QStringList(configurationManager.getCertificateList());
+   ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
+   qDebug() << "\n\nLOADING CERTS" << QStringList(configurationManager.getPinnedCertificates());
    return false;
 }
 
@@ -115,7 +130,7 @@ QString DaemonCertificateCollection::category() const
 
 QVariant DaemonCertificateCollection::icon() const
 {
-   return QVariant();
+   return PixmapManipulationDelegate::instance()->collectionIcon(this,PixmapManipulationDelegate::CollectionIconHint::CERTIFICATE);
 }
 
 bool DaemonCertificateCollection::isEnabled() const
diff --git a/src/daemoncertificatecollection.h b/src/daemoncertificatecollection.h
index 299aeec6..99684a6b 100644
--- a/src/daemoncertificatecollection.h
+++ b/src/daemoncertificatecollection.h
@@ -34,6 +34,7 @@ template<typename T> class CollectionMediator;
  */
 class LIB_EXPORT DaemonCertificateCollection : public CollectionInterface
 {
+
 public:
    explicit DaemonCertificateCollection(CollectionMediator<Certificate>* mediator, const QString& path = QString());
    virtual ~DaemonCertificateCollection();
diff --git a/src/private/account_p.h b/src/private/account_p.h
index 69b1de3d..8f89da6e 100644
--- a/src/private/account_p.h
+++ b/src/private/account_p.h
@@ -55,6 +55,7 @@ public:
    friend class TlsMethodModel;
    friend class BootstrapModelPrivate;
    friend class ContactMethod;
+   friend class Certificate;
 
    //Constructor
    explicit AccountPrivate(Account* acc);
@@ -71,6 +72,7 @@ public:
    QString                    m_LastSipRegistrationStatus;
    unsigned short             m_UseDefaultPort           ;
    bool                       m_RemoteEnabledState       ;
+   uint                       m_InternalId               ;
 
    //Statistic
    bool   m_HaveCalled    ;
@@ -85,6 +87,7 @@ public:
 
    //Getters
    const QString accountDetail(const QString& param) const;
+   uint internalId() const;
 
    //Mutator
    bool merge(Account* account);
@@ -109,16 +112,19 @@ public:
    void save   ();
    void reloadMod() {reload();modify();};
 
-   CredentialModel*          m_pCredentials     ;
-   CodecModel*               m_pCodecModel      ;
-   RingToneModel*            m_pRingToneModel   ;
-   KeyExchangeModel*         m_pKeyExchangeModel;
-   CipherModel*              m_pCipherModel     ;
-   AccountStatusModel*       m_pStatusModel     ;
+   CredentialModel*          m_pCredentials            ;
+   CodecModel*               m_pCodecModel             ;
+   RingToneModel*            m_pRingToneModel          ;
+   KeyExchangeModel*         m_pKeyExchangeModel       ;
+   CipherModel*              m_pCipherModel            ;
+   AccountStatusModel*       m_pStatusModel            ;
    SecurityEvaluationModel*  m_pSecurityEvaluationModel;
-   TlsMethodModel*           m_pTlsMethodModel  ;
-   ProtocolModel*            m_pProtocolModel   ;
-   BootstrapModel*           m_pBootstrapModel  ;
+   TlsMethodModel*           m_pTlsMethodModel         ;
+   ProtocolModel*            m_pProtocolModel          ;
+   BootstrapModel*           m_pBootstrapModel         ;
+   QAbstractItemModel*       m_pKnownCertificates      ;
+   QAbstractItemModel*       m_pBlacklistedCertificates;
+   QAbstractItemModel*       m_pTrustedCertificates    ;
    Account::EditState m_CurrentState;
 
    // State machines
diff --git a/src/private/certificatemodel_p.h b/src/private/certificatemodel_p.h
new file mode 100644
index 00000000..beac98d4
--- /dev/null
+++ b/src/private/certificatemodel_p.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+ *   Copyright (C) 2015 by Savoir-Faire Linux                               *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library 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      *
+ *   Lesser 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 CERTIFICATEMODELPRIVATE_H
+#define CERTIFICATEMODELPRIVATE_H
+
+#include "matrixutils.h"
+
+struct CertificateNode;
+class Account;
+class Certificate;
+
+class CertificateModelPrivate
+{
+public:
+   CertificateModelPrivate(CertificateModel* parent);
+   virtual ~CertificateModelPrivate();
+
+   //Helper
+   CertificateNode* defaultCategory();
+   CertificateNode* createCategory(const QString& name, const QString& col2, const QString& tooltip);
+   CertificateNode* createCategory(const Account* a);
+   CertificateNode* addToTree(Certificate* cert, CertificateNode* category = nullptr);
+   CertificateNode* addToTree(Certificate* cert, Account* a);
+   QModelIndex      createIndex(int r ,int c , void* p);
+   QAbstractItemModel* getModelCommon(CertificateNode* node);
+
+   //Attributes
+   QVector<CertificateNode*>        m_lTopLevelNodes   ;
+   QHash<QString,Certificate*>      m_hCertificates    ;
+   CertificateNode*                 m_pDefaultCategory ;
+   QMutex                           m_CertLoader       ;
+   QHash<const Account*,CertificateNode*> m_hAccToCat  ;
+   QHash<const QString&,CertificateNode*> m_hStrToCat  ;
+   QHash<const Certificate*,CertificateNode*> m_hNodes ;
+   static const Matrix1D<Certificate::Status, const char*> m_StatusMap;
+
+   //Getters
+   QAbstractItemModel* model           (const Certificate* cert) const;
+   QAbstractItemModel* checksModel     (const Certificate* cert) const;
+   QAbstractItemModel* createKnownList (const Account* a       ) const;
+   QAbstractItemModel* createBlockList (const Account* a       ) const;
+   QAbstractItemModel* createTrustList (const Account* a       ) const;
+
+   //Singleton
+   static CertificateModel* m_spInstance;
+
+private:
+   CertificateModel* q_ptr;
+};
+
+#endif
diff --git a/src/qtwrapper/configurationmanager_wrap.h b/src/qtwrapper/configurationmanager_wrap.h
index d74a3db8..56ea61e5 100644
--- a/src/qtwrapper/configurationmanager_wrap.h
+++ b/src/qtwrapper/configurationmanager_wrap.h
@@ -558,9 +558,9 @@ public Q_SLOTS: // METHODS
       return DRing::setCertificateStatus(accountId.toStdString(), certPath.toStdString(), status.toStdString());
    }
 
-   QStringList getCertificatesByStatus(const QString& accountId, const QString& certPath)
+   QStringList getCertificatesByStatus(const QString& accountId, const QString& status)
    {
-      return convertStringList(DRing::getCertificatesByStatus(accountId.toStdString(), certPath.toStdString()));
+      return convertStringList(DRing::getCertificatesByStatus(accountId.toStdString(), status.toStdString()));
    }
 
    MapStringString getTrustRequests(const QString& accountId)
-- 
GitLab