11#include "aclentrydialog_p.h"
12#include "aclmodifyjob.h"
13#include "aclutils_p.h"
14#include "imapaclattribute.h"
15#include "imapresourcesettings.h"
16#include "pimcommonakonadi_debug.h"
17#include "util/pimutil.h"
19#include <Akonadi/CollectionFetchJob>
20#include <Akonadi/ServerManager>
22#include <KEmailAddress>
23#include <KLocalizedString>
26#include <QAbstractListModel>
28#include <QDBusInterface>
30#include <QItemSelectionModel>
50 if (
index.row() < 0 ||
index.row() >= mRights.count()) {
54 const QPair<QByteArray, KIMAP::Acl::Rights>
right = mRights.at(
index.row());
61 return {
static_cast<int>(
right.second)};
62 case PermissionsTextRole:
63 return AclUtils::permissionsToUserString(
right.second);
69 bool setData(
const QModelIndex &
index,
const QVariant &value,
int role =
Qt::EditRole)
override
71 if (
index.row() < 0 ||
index.row() >= mRights.count()) {
75 QPair<QByteArray, KIMAP::Acl::Rights> &
right = mRights[
index.row()];
82 right.second =
static_cast<KIMAP::Acl::Rights
>(value.
toInt());
92 [[nodiscard]]
int rowCount(
const QModelIndex &
parent = QModelIndex())
const override
97 return mRights.count();
101 void setRights(
const QMap<QByteArray, KIMAP::Acl::Rights> &rights)
107 QMap<QByteArray, KIMAP::Acl::Rights>::const_iterator it = rights.cbegin();
108 const QMap<QByteArray, KIMAP::Acl::Rights>::const_iterator itEnd = rights.cend();
109 for (; it != itEnd; ++it) {
110 mRights.append(qMakePair(it.key(), it.value()));
116 [[nodiscard]] QMap<QByteArray, KIMAP::Acl::Rights> rights()
const
118 QMap<QByteArray, KIMAP::Acl::Rights> result;
120 using RightPair = QPair<QByteArray, KIMAP::Acl::Rights>;
121 for (
const RightPair &right : std::as_const(mRights)) {
129 bool insertRows(
int row,
int count,
const QModelIndex &
parent = QModelIndex())
override
132 for (
int i = 0; i < count; ++i) {
133 mRights.insert(row, qMakePair(QByteArray(), KIMAP::Acl::Rights()));
140 bool removeRows(
int row,
int count,
const QModelIndex &
parent = QModelIndex())
override
143 for (
int i = 0; i < count; ++i) {
144 mRights.remove(row, count);
152 QList<QPair<QByteArray, KIMAP::Acl::Rights>> mRights;
155class Q_DECL_HIDDEN
PimCommon::AclManager::AclManagerPrivate
158 AclManagerPrivate(AclManager *qq)
161 mAddAction =
new QAction(
i18nc(
"@action",
"Add Entry..."), q);
166 mEditAction =
new QAction(
i18nc(
"@action",
"Edit Entry..."), q);
167 mEditAction->setEnabled(
false);
172 mDeleteAction =
new QAction(
i18nc(
"@action",
"Remove Entry"), q);
173 mDeleteAction->setEnabled(
false);
178 mModel =
new AclModel(q);
180 mSelectionModel =
new QItemSelectionModel(mModel);
186 ~AclManagerPrivate() =
default;
188 void selectionChanged()
190 const bool itemSelected = !mSelectionModel->selectedIndexes().isEmpty();
194 bool canAdminThisItem = canAdmin;
195 if (canAdmin && itemSelected) {
196 const QModelIndex index = mSelectionModel->selectedIndexes().first();
197 const QString userId = index.
data(AclModel::UserIdRole).
toString();
198 const KIMAP::Acl::Rights rights =
static_cast<KIMAP::Acl::Rights
>(index.
data(AclModel::PermissionsRole).toInt());
202 canAdminThisItem =
false;
206 mAddAction->setEnabled(canAdmin);
207 mEditAction->setEnabled(itemSelected && canAdminThisItem);
208 mDeleteAction->setEnabled(itemSelected && canAdminThisItem);
214 dlg.setWindowTitle(
i18nc(
"@title:window",
"Add ACL"));
219 const QString userId = dlg.userId();
221 for (
const QString &addr : lstAddresses) {
222 if (mModel->insertRow(mModel->rowCount())) {
223 const QModelIndex index = mModel->index(mModel->rowCount() - 1, 0);
225 mModel->setData(index, extractedAddress, AclModel::UserIdRole);
226 mModel->setData(index,
static_cast<int>(dlg.permissions()), AclModel::PermissionsRole);
235 if (mEditAction->isEnabled()) {
236 const QModelIndex index = mSelectionModel->selectedIndexes().first();
237 const QString userId = index.
data(AclModel::UserIdRole).
toString();
238 const KIMAP::Acl::Rights permissions =
static_cast<KIMAP::Acl::Rights
>(index.
data(AclModel::PermissionsRole).toInt());
241 dlg.setWindowTitle(
i18nc(
"@title:window",
"Edit ACL"));
242 dlg.setUserId(userId);
243 dlg.setPermissions(permissions);
249 if (lstAddresses.
count() == 1) {
251 mModel->setData(index,
static_cast<int>(dlg.permissions()), AclModel::PermissionsRole);
254 bool firstElement =
true;
255 for (
const QString &addr : lstAddresses) {
258 mModel->setData(index,
static_cast<int>(dlg.permissions()), AclModel::PermissionsRole);
259 firstElement =
false;
261 if (mModel->insertRow(mModel->rowCount())) {
262 const QModelIndex rowindex = mModel->index(mModel->rowCount() - 1, 0);
264 mModel->setData(rowindex,
static_cast<int>(dlg.permissions()), AclModel::PermissionsRole);
275 const QModelIndex index = mSelectionModel->selectedIndexes().first();
276 const QString userId = index.
data(AclModel::UserIdRole).
toString();
278 if (mImapUserName == userId) {
281 i18n(
"Do you really want to remove your own permissions for this folder? "
282 "You will not be able to access it afterwards."),
283 i18nc(
"@title:window",
"Remove"))) {
289 i18n(
"Do you really want to remove these permissions for this folder?"),
290 i18nc(
"@title:window",
"Remove"))) {
295 mModel->removeRow(index.
row(), QModelIndex());
299 void setCollection(
const Akonadi::Collection &collection)
301 mCollection = collection;
304 const auto attribute = collection.
attribute<PimCommon::ImapAclAttribute>();
305 const QMap<QByteArray, KIMAP::Acl::Rights> rights = attribute->rights();
307 QString resource = collection.
resource();
308 if (resource.
contains(
"akonadi_kolabproxy_resource"_L1)) {
311 QDBusInterface interface(basename, QStringLiteral(
"/KolabProxy"));
312 if (interface.isValid()) {
313 QDBusReply<QString> reply = interface.call(QStringLiteral(
"imapResourceForCollection"), collection.
remoteId().
toLongLong());
319 OrgKdeAkonadiImapSettingsInterface *imapSettingsInterface = PimCommon::Util::createImapSettingsInterface(resource);
323 if (imapSettingsInterface && imapSettingsInterface->isValid()) {
324 QDBusReply<QString> reply = imapSettingsInterface->userName();
329 reply = imapSettingsInterface->imapServer();
334 qCDebug(PIMCOMMONAKONADI_LOG) <<
" collection has not imap as resources: " << collection.
resource();
336 delete imapSettingsInterface;
338 mImapUserName = loginName;
339 if (!rights.contains(loginName.
toUtf8())) {
340 const QString guessedUserName = AclUtils::guessUserName(loginName, serverName);
341 if (rights.contains(guessedUserName.
toUtf8())) {
342 mImapUserName = guessedUserName;
346 mUserRights = rights[mImapUserName.toUtf8()];
348 mModel->setRights(rights);
353 AclModel *mModel =
nullptr;
354 QItemSelectionModel *mSelectionModel =
nullptr;
355 QAction *mAddAction =
nullptr;
356 QAction *mEditAction =
nullptr;
357 QAction *mDeleteAction =
nullptr;
359 Akonadi::Collection mCollection;
360 QString mImapUserName;
361 KIMAP::Acl::Rights mUserRights;
362 bool mChanged =
false;
365AclManager::AclManager(
QObject *parent)
367 , d(new AclManagerPrivate(this))
371AclManager::~AclManager() =
default;
375 d->setCollection(collection);
376 Q_EMIT collectionChanged(d->mCollection);
380Akonadi::Collection AclManager::collection()
const
382 return d->mCollection;
385QAbstractItemModel *AclManager::model()
const
390QItemSelectionModel *AclManager::selectionModel()
const
392 return d->mSelectionModel;
395QAction *AclManager::addAction()
const
397 return d->mAddAction;
400QAction *AclManager::editAction()
const
402 return d->mEditAction;
405QAction *AclManager::deleteAction()
const
407 return d->mDeleteAction;
410void AclManager::save(
bool recursive)
412 if (!d->mCollection.isValid() || !d->mChanged) {
419 qCDebug(PIMCOMMONAKONADI_LOG) <<
" collection Fetch error" << job->errorString();
423 if (job->collections().isEmpty()) {
424 qCDebug(PIMCOMMONAKONADI_LOG) <<
" collection list Fetched is Empty ";
428 d->mCollection = job->collections().at(0);
432 auto modifyAclJob =
new PimCommon::AclModifyJob;
433 modifyAclJob->setCurrentRight(d->mModel->rights());
434 modifyAclJob->setTopLevelCollection(d->mCollection);
435 modifyAclJob->setRecursive(recursive);
436 modifyAclJob->start();
439void AclManager::setChanged(
bool b)
444#include "moc_aclmanager.cpp"
const T * attribute() const
static QString agentServiceName(ServiceAgentType agentType, const QString &identifier)
KCODECS_EXPORT QStringList splitAddressList(const QString &aStr)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
ButtonCode warningContinueCancel(QWidget *parent, const QString &text, const QString &title=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
void beginInsertRows(const QModelIndex &parent, int first, int last)
void beginRemoveRows(const QModelIndex &parent, int first, int last)
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles)
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const=0
virtual QModelIndex parent(const QModelIndex &index) const const=0
QAbstractListModel(QObject *parent)
void triggered(bool checked)
bool isValid() const const
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
const_reference at(qsizetype i) const const
qsizetype count() const const
iterator insert(const Key &key, const T &value)
QVariant data(int role) const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QString fromLatin1(QByteArrayView str)
qlonglong toLongLong(bool *ok, int base) const const
QByteArray toUtf8() const const
QTextStream & right(QTextStream &stream)
QByteArray toByteArray() const const
int toInt(bool *ok) const const
QString toString() const const