8#include "aclmodifyjob.h"
11#include "aclutils_p.h"
12#include "imapresourcesettings.h"
13#include "pimcommonakonadi_debug.h"
14#include "util/pimutil.h"
15#include <Akonadi/ServerManager>
16#include <KEmailAddress>
18#include "imapaclattribute.h"
20#include <Akonadi/CollectionFetchJob>
21#include <Akonadi/CollectionFetchScope>
22#include <Akonadi/CollectionModifyJob>
23#include <Akonadi/ContactGroupExpandJob>
24#include <Akonadi/ContactGroupSearchJob>
25#include <KContacts/Addressee>
26#include <KLocalizedString>
28#include <QDBusInterface>
34AclModifyJob::AclModifyJob(
QObject *parent)
37 connect(
this, &AclModifyJob::searchContactDone,
this, &AclModifyJob::slotModifyAcl);
38 connect(
this, &AclModifyJob::searchNextContact,
this, &AclModifyJob::searchContact);
41AclModifyJob::~AclModifyJob() =
default;
43void AclModifyJob::searchContact()
45 const QMap<QByteArray, KIMAP::Acl::Rights>::const_iterator itEnd = mCurrentRight.cend();
47 auto searchJob =
new Akonadi::ContactGroupSearchJob(
this);
49 searchJob->setLimit(1);
50 connect(searchJob, &Akonadi::ContactGroupSearchJob::result,
this, &AclModifyJob::slotGroupSearchResult);
52 Q_EMIT searchContactDone();
56void AclModifyJob::slotGroupSearchResult(KJob *job)
59 if (!searchJob->contactGroups().isEmpty()) {
60 auto expandJob =
new Akonadi::ContactGroupExpandJob(searchJob->contactGroups().at(0),
this);
61 if (expandJob->exec()) {
63 for (
const KContacts::Addressee &contact : lstContacts) {
66 mNewRight[rawEmail] = mIt.value();
73 mNewRight[rawEmail] = mIt.value();
77 Q_EMIT searchNextContact();
80void AclModifyJob::start()
82 if (!mTopLevelCollection.isValid()) {
86#ifdef SEARCHCONTACT_AKONADI
87 mIt = mCurrentRight.cbegin();
90 const QMap<QByteArray, KIMAP::Acl::Rights> rights = mCurrentRight;
91 QMap<QByteArray, KIMAP::Acl::Rights>::const_iterator it = rights.
cbegin();
92 const QMap<QByteArray, KIMAP::Acl::Rights>::const_iterator itEnd = rights.
cend();
93 for (; it != itEnd; ++it) {
96 mNewRight[rawEmail] = it.value();
103void AclModifyJob::slotModifyAcl()
109 connect(job, &Akonadi::CollectionFetchJob::finished,
this, [
this](KJob *job) {
111 qCWarning(PIMCOMMONAKONADI_LOG) << job->
errorString();
112 slotFetchCollectionFailed();
114 auto fetch =
static_cast<Akonadi::CollectionFetchJob *
>(job);
115 slotFetchCollectionFinished(fetch->collections());
119 changeAcl(mTopLevelCollection);
123bool AclModifyJob::canAdministrate(
const PimCommon::ImapAclAttribute *attribute,
const Akonadi::Collection &collection)
const
125 if (!attribute || !collection.
isValid()) {
128 const QMap<QByteArray, KIMAP::Acl::Rights> rights = attribute->rights();
130 QString resource = collection.
resource();
131 if (resource.
contains(
"akonadi_kolabproxy_resource"_L1)) {
133 QDBusInterface interface(basename, QStringLiteral(
"/KolabProxy"));
134 if (interface.isValid()) {
135 QDBusReply<QString> reply = interface.call(QStringLiteral(
"imapResourceForCollection"), collection.
remoteId().
toLongLong());
141 OrgKdeAkonadiImapSettingsInterface *imapSettingsInterface = PimCommon::Util::createImapSettingsInterface(resource);
145 if (imapSettingsInterface->isValid()) {
146 QDBusReply<QString> reply = imapSettingsInterface->userName();
151 reply = imapSettingsInterface->imapServer();
156 qCDebug(PIMCOMMONAKONADI_LOG) <<
" collection has not imap as resources: " << collection.
resource();
158 delete imapSettingsInterface;
160 QString imapUserName = loginName;
162 const QString guessedUserName = AclUtils::guessUserName(loginName, serverName);
164 imapUserName = guessedUserName;
170void AclModifyJob::setCurrentRight(
const QMap<QByteArray, KIMAP::Acl::Rights> ¤tRight)
172 mCurrentRight = currentRight;
175void AclModifyJob::changeAcl(
const Akonadi::Collection &collection)
177 if (collection.
hasAttribute<PimCommon::ImapAclAttribute>()) {
178 Akonadi::Collection mutableCollection = collection;
179 auto attribute = mutableCollection.
attribute<PimCommon::ImapAclAttribute>();
180 if (canAdministrate(attribute, mutableCollection)) {
181 attribute->setRights(mNewRight);
182 auto modifyJob =
new Akonadi::CollectionModifyJob(mutableCollection);
186 checkNewCollection();
190void AclModifyJob::checkNewCollection()
193 if (mCurrentIndex < mRecursiveCollection.count()) {
194 changeAcl(mRecursiveCollection.at(mCurrentIndex));
200void AclModifyJob::slotModifyDone(KJob *job)
203 qCDebug(PIMCOMMONAKONADI_LOG) <<
" Error during modify collection " << job->
errorString();
205 checkNewCollection();
210 QStringList folderNames;
211 for (
const Akonadi::Collection &col : collectionList) {
212 if (col.hasAttribute<PimCommon::ImapAclAttribute>()) {
213 const auto attribute = col.attribute<PimCommon::ImapAclAttribute>();
214 if (canAdministrate(attribute, col)) {
217 Akonadi::Collection cur = col;
223 for (
const Akonadi::Collection &it : collectionList) {
224 if (it.id() == cur.
id()) {
231 }
while (parentFound);
235 qCDebug(PIMCOMMONAKONADI_LOG) <<
"AclModifyJob: No rights to administer " << col.name();
238 qCDebug(PIMCOMMONAKONADI_LOG) <<
"AclModifyJob: Collection " << col.name() <<
"has no ACL.";
243 i18n(
"Do you really want to apply the folder's permissions to these subfolders?"),
245 i18nc(
"@title:window",
"Apply Permissions"))
248 qCDebug(PIMCOMMONAKONADI_LOG) <<
"AclModifyJob: User canceled .";
251 mRecursiveCollection = collectionList;
252 changeAcl(mTopLevelCollection);
255void AclModifyJob::slotFetchCollectionFailed()
257 qCDebug(PIMCOMMONAKONADI_LOG) <<
"fetch collection failed";
261void AclModifyJob::setTopLevelCollection(
const Akonadi::Collection &topLevelCollection)
263 mTopLevelCollection = topLevelCollection;
266void AclModifyJob::setRecursive(
bool recursive)
268 mRecursive = recursive;
271#include "moc_aclmodifyjob.cpp"
const T * attribute() const
Collection & parentCollection()
bool hasAttribute() const
static QString agentServiceName(ServiceAgentType agentType, const QString &identifier)
virtual QString errorString() const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
QString fullName(const PartType &type)
ButtonCode warningContinueCancelList(QWidget *parent, const QString &text, const QStringList &strlist, const QString &title=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
bool isEmpty() const const
bool isValid() const const
const_iterator cbegin() const const
const_iterator cend() const const
bool contains(const Key &key) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
T qobject_cast(QObject *object)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QString fromLatin1(QByteArrayView str)
QString right(qsizetype n) const const
qsizetype size() const const
qlonglong toLongLong(bool *ok, int base) const const
QByteArray toUtf8() const const
void sort(Qt::CaseSensitivity cs)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)