From 04bd4a9700a4ec1dd5933ed8a4004bd87a178e14 Mon Sep 17 00:00:00 2001
From: Nicolas Jager <nicolas.jager@savoirfairelinux.com>
Date: Wed, 17 May 2017 13:12:54 -0400
Subject: [PATCH] PersonModel : implementation of BannedContactModel

- add a new class BannedContactModel. This model loads at start of the
client a list from the daemon to figure which ContactMethods are
banned.

- it updates the list (for now, we can only ban) when a peer is banned.

[Guillaume: fix typo in ci msg]

Change-Id: I2367c8918dd4f743ebbce2b0c1c90e5fde71c45b
---
 CMakeLists.txt               |   2 +
 src/account.cpp              |  12 +++
 src/account.h                |   2 +
 src/accountmodel.cpp         |  17 +++++
 src/bannedcontactmodel.cpp   | 141 +++++++++++++++++++++++++++++++++++
 src/bannedcontactmodel.h     |  54 ++++++++++++++
 src/private/account_p.h      |   1 +
 src/private/accountmodel_p.h |   1 +
 8 files changed, 230 insertions(+)
 create mode 100644 src/bannedcontactmodel.cpp
 create mode 100644 src/bannedcontactmodel.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index a932d139..df173066 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -290,6 +290,7 @@ SET( libringclient_LIB_SRCS
   src/audio/ringtonedevicemodel.cpp
   src/audio/settings.cpp
   src/media/recordingmodel.cpp
+  src/bannedcontactmodel.cpp
 
   #Data collections
   src/transitionalpersonbackend.cpp
@@ -440,6 +441,7 @@ SET( libringclient_LIB_HDRS
   src/itemdataroles.h
   src/smartinfohub.h
   src/usage_statistics.h
+  src/bannedcontactmodel.h
 )
 
 SET(libringclient_video_LIB_HDRS
diff --git a/src/account.cpp b/src/account.cpp
index 93c7ebeb..0fe5bd89 100644
--- a/src/account.cpp
+++ b/src/account.cpp
@@ -70,6 +70,9 @@
 #include "daemoncertificatecollection.h"
 #include "private/securityevaluationmodel_p.h"
 #include "extensions/securityevaluationextension.h"
+#include "bannedcontactmodel.h"
+
+// define
 #define TO_BOOL ?"true":"false"
 #define IS_TRUE == "true"
 
@@ -612,6 +615,15 @@ PendingContactRequestModel* Account::pendingContactRequestModel() const
    return d_ptr->m_pPendingContactRequestModel;
 }
 
+BannedContactModel*
+Account::bannedContactModel() const
+{
+   if (!d_ptr->m_pBannedContactModel)
+      d_ptr->m_pBannedContactModel = new BannedContactModel(const_cast<Account*>(this));
+
+   return d_ptr->m_pBannedContactModel;
+}
+
 NetworkInterfaceModel* Account::networkInterfaceModel() const
 {
    if (!d_ptr->m_pNetworkInterfaceModel) {
diff --git a/src/account.h b/src/account.h
index 36612b6a..11b0f718 100644
--- a/src/account.h
+++ b/src/account.h
@@ -50,6 +50,7 @@ class KeyExchangeModelPrivate ;
 class PendingContactRequestModel;
 class Profile;
 class ContactRequest;
+class BannedContactModel;
 
 //Private
 class AccountPrivate;
@@ -381,6 +382,7 @@ class LIB_EXPORT Account : public ItemBase {
       QAbstractItemModel*       bannedCertificatesModel    () const;
       QAbstractItemModel*       allowedCertificatesModel   () const;
       PendingContactRequestModel* pendingContactRequestModel   () const;
+      BannedContactModel* bannedContactModel() const;
 
       Q_INVOKABLE RoleState  roleState (Account::Role role) const;
       Q_INVOKABLE RoleStatus roleStatus(Account::Role role) const;
diff --git a/src/accountmodel.cpp b/src/accountmodel.cpp
index 11ff56f6..af87936a 100644
--- a/src/accountmodel.cpp
+++ b/src/accountmodel.cpp
@@ -53,6 +53,7 @@
 #include "person.h"
 #include "private/vcardutils.h"
 #include "phonedirectorymodel.h"
+#include "bannedcontactmodel.h"
 
 QHash<QByteArray,AccountPlaceHolder*> AccountModelPrivate::m_hsPlaceHolder;
 
@@ -96,6 +97,8 @@ void AccountModelPrivate::init()
             &AccountModelPrivate::slotExportOnRingEnded, Qt::QueuedConnection);
     connect(&configurationManager, &ConfigurationManagerInterface::migrationEnded, this,
             &AccountModelPrivate::slotMigrationEnded, Qt::QueuedConnection);
+    connect(&configurationManager, &ConfigurationManagerInterface::contactRemoved, this,
+            &AccountModelPrivate::slotContactRemoved, Qt::QueuedConnection);
 }
 
 ///Destructor
@@ -529,6 +532,20 @@ AccountModelPrivate::slotMigrationEnded(const QString& accountId, const QString&
         emit a->migrationEnded(status);
 }
 
+/**
+ * slot function used with ConfigurationManagerInterface::contactRemoved signal
+ */
+void
+AccountModelPrivate::slotContactRemoved(const QString &accountID, const QString &uri, bool banned)
+{
+    if (not banned)
+        return;
+
+    auto account = q_ptr->getById(accountID.toLatin1());
+    auto cm = PhoneDirectoryModel::instance().getNumber(uri, account);
+    account->bannedContactModel()->add(cm);
+}
+
 ///Update accounts
 void AccountModel::update()
 {
diff --git a/src/bannedcontactmodel.cpp b/src/bannedcontactmodel.cpp
new file mode 100644
index 00000000..e5e8a1b7
--- /dev/null
+++ b/src/bannedcontactmodel.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+ *   Copyright (C) 2017 by Savoir-faire Linux                               *
+ *   Author : Nicolas Jäger <nicolas.jager@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/>.  *
+ ***************************************************************************/
+#include "bannedcontactmodel.h"
+
+//Qt
+#include <QtCore/QDateTime>
+
+// LRC
+#include "dbus/configurationmanager.h"
+#include "contactmethod.h"
+#include "phonedirectorymodel.h"
+
+#include <contactrequest.h>
+#include <certificate.h>
+#include <account.h>
+#include "private/pendingcontactrequestmodel_p.h"
+#include "person.h"
+#include "contactmethod.h"
+
+class BannedContactModelPrivate
+{
+public:
+    //Constructor
+    BannedContactModelPrivate(BannedContactModel* parent);
+
+    //Attributes
+    QList<ContactMethod*> m_lBanned;
+    Account*              m_pAccount ;
+
+private:
+    BannedContactModel* q_ptr;
+};
+
+/**
+ * constructor of BannedContactModelPrivate.
+ */
+BannedContactModelPrivate::BannedContactModelPrivate(BannedContactModel* p) : q_ptr(p)
+{
+}
+
+/**
+ * constructor of BannedContactModel.
+ */
+BannedContactModel::BannedContactModel(Account* a) : QAbstractTableModel(a),
+d_ptr(new BannedContactModelPrivate(this))
+{
+    d_ptr->m_pAccount = a;
+
+    // Load the contacts associated from the daemon and create the cms.
+    const auto account_contacts
+        = static_cast<QVector<QMap<QString, QString>>>(ConfigurationManager::instance().getContacts(a->id().data()));
+
+    if (a->protocol() == Account::Protocol::RING) {
+        for (auto contact_info : account_contacts) {
+            if (contact_info["banned"] == "true") {
+                auto cm = PhoneDirectoryModel::instance().getNumber(contact_info["id"], a);
+                add(cm);
+            }
+        }
+    }
+}
+
+/**
+ * destructor of BannedContactModel.
+ */
+BannedContactModel::~BannedContactModel()
+{
+    delete d_ptr;
+}
+
+/**
+ * QAbstractTableModel function used to return the data.
+ */
+QVariant
+BannedContactModel::data( const QModelIndex& index, int role ) const
+{
+    if (!index.isValid())
+        return QVariant();
+
+    switch(index.column()) {
+    case Columns::PEER_ID:
+        switch(role) {
+        case Qt::DisplayRole:
+            return d_ptr->m_lBanned[index.row()]->bestId();
+        }
+    break;
+    case Columns::COUNT__:
+        switch(role) {
+        case Qt::DisplayRole:
+            return static_cast<int>(BannedContactModel::Columns::COUNT__);
+        }
+    break;
+    }
+
+   return QVariant();
+}
+
+/**
+ * return the number of rows from the model.
+ */
+int
+BannedContactModel::rowCount( const QModelIndex& parent ) const
+{
+    return parent.isValid()? 0 : d_ptr->m_lBanned.size();
+}
+
+/**
+ * return the number of columns from the model.
+ */
+int
+BannedContactModel::columnCount( const QModelIndex& parent ) const
+{
+    return parent.isValid()? 0 : static_cast<int>(BannedContactModel::Columns::COUNT__);
+}
+
+/**
+ * this function add a ContactMethod to the banned list.
+ * @param cm, the ContactMethod to add to the list.
+ */
+void
+BannedContactModel::add(ContactMethod* cm)
+{
+    beginInsertRows(QModelIndex(),d_ptr->m_lBanned.size(),d_ptr->m_lBanned.size());
+    d_ptr->m_lBanned << cm;
+    endInsertRows();
+}
diff --git a/src/bannedcontactmodel.h b/src/bannedcontactmodel.h
new file mode 100644
index 00000000..2c19b833
--- /dev/null
+++ b/src/bannedcontactmodel.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+ *   Copyright (C) 2017 by Savoir-faire Linux                               *
+ *   Author : Nicolas Jäger <nicolas.jager@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/>.  *
+ ***************************************************************************/
+#pragma once
+
+#include <QtCore/QAbstractTableModel>
+#include <typedefs.h>
+
+class Account;
+class BannedContactModelPrivate;
+class ContactMethod;
+class ContactRequest;
+
+class LIB_EXPORT BannedContactModel : public QAbstractTableModel
+{
+    Q_OBJECT
+
+public:
+    BannedContactModel(Account* a);
+
+    enum Columns {
+        PEER_ID,
+        COUNT__
+    };
+
+    // Model functions
+    virtual QVariant      data        ( const QModelIndex& index, int role = Qt::DisplayRole     ) const override;
+    virtual int           rowCount    ( const QModelIndex& parent = QModelIndex()                ) const override;
+    virtual int           columnCount ( const QModelIndex& parent = QModelIndex()                ) const override;
+
+    // Helper
+    void add(ContactMethod* cm);
+
+private:
+    virtual ~BannedContactModel();
+
+    BannedContactModelPrivate* d_ptr;
+    Q_DECLARE_PRIVATE(BannedContactModel)
+
+};
diff --git a/src/private/account_p.h b/src/private/account_p.h
index 1e95e629..4338eb50 100644
--- a/src/private/account_p.h
+++ b/src/private/account_p.h
@@ -119,6 +119,7 @@ public:
    Profile*                     m_pProfile {nullptr}       ;
    PendingContactRequestModel*    m_pPendingContactRequestModel;
    Account::ContactMethods      m_NumbersFromDaemon        ;
+   BannedContactModel* m_pBannedContactModel {nullptr};
 
    QHash<int, Account::RoleStatus> m_hRoleStatus;
 
diff --git a/src/private/accountmodel_p.h b/src/private/accountmodel_p.h
index 50449235..076cfade 100644
--- a/src/private/accountmodel_p.h
+++ b/src/private/accountmodel_p.h
@@ -75,4 +75,5 @@ public Q_SLOTS:
    void slotKownDevicesChanged(const QString& accountId, const MapStringString& devices);
    void slotExportOnRingEnded(const QString& accountId, int status, const QString& pin);
    void slotMigrationEnded(const QString& accountId, const QString& result);
+   void slotContactRemoved(const QString &accountID, const QString &uri, bool banned);
 };
-- 
GitLab