File indexing completed on 2024-04-21 05:47:44
0001 /************************************************************************************* 0002 * Copyright (C) 2012 by Alejandro Fiestas Olivares <afiestas@kde.org> * 0003 * * 0004 * This program is free software; you can redistribute it and/or * 0005 * modify it under the terms of the GNU General Public License * 0006 * as published by the Free Software Foundation; either version 2 * 0007 * of the License, or (at your option) any later version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, * 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0012 * GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License * 0015 * along with this program; if not, write to the Free Software * 0016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 0017 *************************************************************************************/ 0018 0019 #include "sambamount.h" 0020 #include "mountinfo.h" 0021 #include "ui_kcm.h" 0022 0023 #include <QStackedLayout> 0024 0025 #include <QDebug> 0026 #include <QAction> 0027 #include <QDBusMessage> 0028 #include <QDBusConnection> 0029 #include <QDBusArgument> 0030 #include <KAuthAction> 0031 #include <KAuthExecuteJob> 0032 #include <KPluginFactory> 0033 #include <KSharedConfig> 0034 #include <unistd.h> 0035 #include "kpasswdserver_interface.h" 0036 0037 using namespace KAuth; 0038 0039 K_PLUGIN_FACTORY(SambaMountFactory, registerPlugin<SambaMount>();) 0040 K_EXPORT_PLUGIN(SambaMountFactory("sambamount", "sambamount")) 0041 0042 SambaMount::SambaMount(QWidget *parent, const QVariantList &args) 0043 : KCModule(parent) 0044 , m_layout(new QStackedLayout) 0045 { 0046 if (args.count() > 1 && args.first() == QLatin1String("--new")) { 0047 m_selectNew = true; 0048 } 0049 0050 setButtons(KCModule::Help); 0051 m_ui = new Ui::KCMSambaMount(); 0052 m_ui->setupUi(this); 0053 0054 m_ui->mountInfo->setLayout(m_layout); 0055 m_ui->mountList->setIconSize(QSize(48, 48)); 0056 m_ui->errorWidget->setMessageType(KMessageWidget::Error); 0057 m_ui->errorWidget->hide(); 0058 0059 connect(m_ui->remoteBtn, SIGNAL(clicked(bool)), SLOT(rmBtnClicked())); 0060 connect(m_ui->addBtn, SIGNAL(clicked(bool)), SLOT(addBtnClicked())); 0061 connect(m_ui->mountList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), 0062 this, SLOT(currentItemChanged(QListWidgetItem*,QListWidgetItem*))); 0063 0064 QMetaObject::invokeMethod(this, "initSambaMounts", Qt::QueuedConnection); 0065 0066 m_interface = new OrgKdeKPasswdServerInterface("org.kde.kpasswdserver", "/modules/kpasswdserver", QDBusConnection::sessionBus(), this); 0067 } 0068 0069 SambaMount::~SambaMount() 0070 { 0071 delete m_ui; 0072 } 0073 0074 void SambaMount::initSambaMounts() 0075 { 0076 KConfigGroup configMounts = mounts(); 0077 Q_FOREACH(const QString &id, configMounts.groupList()) { 0078 addMount(configMounts.group(id)); 0079 } 0080 0081 MountInfo *widget = new MountInfo(m_interface, mounts(), this); 0082 connect(widget, &MountInfo::changed, this, [this]() { changed(true); }); 0083 connect(widget, SIGNAL(mountCreated(KConfigGroup)), SLOT(mountCreated(KConfigGroup))); 0084 0085 m_layout->addWidget(widget); 0086 0087 m_newMountItem = new QListWidgetItem(); 0088 m_newMountItem->setIcon(QIcon::fromTheme("applications-education-miscellaneous")); 0089 m_newMountItem->setText(i18n("New Share")); 0090 m_newMountItem->setData(Qt::UserRole, QVariant(i18n("New Share"))); 0091 m_newMountItem->setData(Qt::UserRole + 1, QVariant::fromValue<QWidget *>(widget)); 0092 0093 m_ui->mountList->addItem(m_newMountItem); 0094 0095 if (m_ui->mountList->count() == 0 || m_selectNew) { 0096 m_ui->mountList->setCurrentItem(m_newMountItem); 0097 return; 0098 } 0099 0100 m_ui->mountList->setCurrentItem(m_ui->mountList->item(0)); 0101 } 0102 0103 void SambaMount::save() 0104 { 0105 QListWidgetItem* item = m_ui->mountList->currentItem(); 0106 QWidget *widget = item->data(Qt::UserRole + 1).value<QWidget *>(); 0107 MountInfo *info = qobject_cast<MountInfo*>(widget); 0108 if (info) { 0109 info->saveConfig(); 0110 if (!info->id().isEmpty()) { 0111 mountSamba(mounts().group(info->id())); 0112 } 0113 } 0114 } 0115 0116 void SambaMount::currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous) 0117 { 0118 if (!current) { 0119 return; 0120 } 0121 0122 m_ui->mountInfo->setTitle(current->text()); 0123 m_layout->setCurrentWidget(current->data(Qt::UserRole + 1).value<QWidget *>()); 0124 m_ui->remoteBtn->setEnabled(current != m_newMountItem); 0125 } 0126 0127 void SambaMount::mountCreated(KConfigGroup group) 0128 { 0129 qDebug() << "New Mount Created"; 0130 QListWidgetItem *item = new QListWidgetItem(); 0131 item->setIcon(QIcon::fromTheme("network-server")); 0132 item->setText(QUrl(group.readEntry("fullSambaUrl", "")).fileName() + " on " + group.readEntry("hostname", "")); 0133 item->setData(Qt::UserRole, group.readEntry("ip", "")); 0134 item->setData(Qt::UserRole + 1, QVariant::fromValue<QWidget *>(qobject_cast<QWidget *>(sender()))); 0135 item->setData(Qt::UserRole + 2, group.name()); 0136 0137 m_ui->mountList->addItem(item); 0138 0139 MountInfo *widget = new MountInfo(m_interface, mounts(), this); 0140 connect(widget, &MountInfo::changed, this, [this]() { changed(true); }); 0141 connect(widget, SIGNAL(mountCreated(KConfigGroup)), SLOT(mountCreated(KConfigGroup))); 0142 0143 m_layout->addWidget(widget); 0144 0145 m_newMountItem->setData(Qt::UserRole + 1, QVariant::fromValue<QWidget *>(widget)); 0146 0147 int row = m_ui->mountList->row(m_newMountItem); 0148 0149 m_ui->mountList->takeItem(row); 0150 m_ui->mountList->insertItem(row, item); 0151 m_ui->mountList->addItem(m_newMountItem); 0152 m_ui->mountList->setCurrentItem(item); 0153 0154 mountSamba(group); 0155 } 0156 0157 void SambaMount::mountEditted(KConfigGroup group) 0158 { 0159 qDebug() << "Mount editted" << group.name(); 0160 if (umountSamba(group.name())) 0161 mountSamba(group); 0162 } 0163 0164 void SambaMount::addBtnClicked() 0165 { 0166 m_ui->mountList->setCurrentItem(m_newMountItem, QItemSelectionModel::SelectCurrent); 0167 } 0168 0169 void SambaMount::rmBtnClicked() 0170 { 0171 QListWidgetItem *item = m_ui->mountList->currentItem(); 0172 if (item == m_newMountItem) { 0173 return; 0174 } 0175 0176 QString groupName = item->data(Qt::UserRole + 2).toString(); 0177 umountSamba(groupName); 0178 QDir().rmdir(mounts().group(groupName).readEntry("mountPoint", "")); 0179 mounts().deleteGroup(groupName); 0180 0181 QWidget *widget = item->data(Qt::UserRole + 1).value<QWidget *>(); 0182 item->setData(Qt::UserRole + 1, 0); 0183 m_layout->removeWidget(widget); 0184 m_ui->mountList->removeItemWidget(item); 0185 0186 delete widget; 0187 delete item; 0188 } 0189 0190 KConfigGroup SambaMount::mounts() 0191 { 0192 return KSharedConfig::openConfig("samba-mounter")->group("mounts"); 0193 } 0194 0195 void SambaMount::addMount(KConfigGroup group) 0196 { 0197 MountInfo *info = new MountInfo(m_interface, mounts(), this); 0198 connect(info, SIGNAL(mountEditted(KConfigGroup)), SLOT(mountEditted(KConfigGroup))); 0199 connect(info, &MountInfo::changed, this, [this]() { changed(true); }); 0200 info->setConfigGroup(group.name()); 0201 m_layout->addWidget(info); 0202 0203 QListWidgetItem *item = new QListWidgetItem(); 0204 item->setIcon(QIcon::fromTheme("network-server")); 0205 item->setText(QUrl(group.readEntry("fullSambaUrl", "")).fileName() + " on " + group.readEntry("hostname", "")); 0206 item->setData(Qt::UserRole, group.readEntry("ip", "")); 0207 item->setData(Qt::UserRole + 1, QVariant::fromValue<QWidget *>(info)); 0208 item->setData(Qt::UserRole + 2, group.name()); 0209 0210 m_ui->mountList->addItem(item); 0211 } 0212 0213 bool SambaMount::mountSamba(KConfigGroup group) 0214 { 0215 qDebug() << "Mounting samba: " << group.name(); 0216 Action readAction("org.kde.sambamounter.mount"); 0217 readAction.setHelperId("org.kde.sambamounter"); 0218 0219 readAction.addArgument("uid", QString::number(getuid())); 0220 readAction.addArgument("ip", group.readEntry("ip", "")); 0221 readAction.addArgument("locale", qgetenv("LANG")); 0222 readAction.addArgument("path", qgetenv("PATH")); 0223 readAction.addArgument("sambaDir", group.readEntry("sambaDir", "").toLocal8Bit().toBase64()); 0224 readAction.addArgument("mountPoint", group.readEntry("mountPoint", "").toLocal8Bit().toBase64()); 0225 readAction.addArgument("username", group.readEntry("username", "").toLocal8Bit().toBase64()); 0226 readAction.addArgument("password", group.readEntry("password", "").toLocal8Bit().toBase64()); 0227 return executeJob(readAction.execute()); 0228 } 0229 0230 bool SambaMount::umountSamba(const QString& name) 0231 { 0232 KConfigGroup group = mounts().group(name); 0233 Action readAction("org.kde.sambamounter.umount"); 0234 readAction.setHelperId("org.kde.sambamounter"); 0235 0236 readAction.addArgument("locale", qgetenv("LANG")); 0237 readAction.addArgument("path", qgetenv("PATH")); 0238 readAction.addArgument("mountPoint", group.readEntry("mountPoint", "").toLocal8Bit().toBase64()); 0239 return executeJob(readAction.execute()); 0240 } 0241 0242 bool SambaMount::executeJob(ExecuteJob* reply) 0243 { 0244 if (!reply->action().isValid()) { 0245 m_ui->errorWidget->setText(i18n("Couldn't find action '%1'", reply->action().name())); 0246 m_ui->errorWidget->animatedShow(); 0247 qWarning() << "error while executing" << m_ui->errorWidget->text(); 0248 return false; 0249 } 0250 0251 bool ret = reply->exec(); 0252 if (ret) { 0253 qDebug() << "executed" << reply->action().name() << reply->data(); 0254 if (reply->data()["exitCode"] != 0) { 0255 m_ui->errorWidget->setText(i18n("Error triggering mount:\n%1", reply->data()["error"].toString())); 0256 m_ui->errorWidget->setToolTip(m_ui->errorWidget->text()); 0257 m_ui->errorWidget->animatedShow(); 0258 } else 0259 m_ui->errorWidget->animatedHide(); 0260 } else { 0261 m_ui->errorWidget->setText(i18n("Error %1 on '%2':\n%3", reply->error(), reply->action().name(), reply->errorString())); 0262 m_ui->errorWidget->animatedShow(); 0263 qWarning() << "error while executing" << m_ui->errorWidget->text(); 0264 } 0265 return ret; 0266 } 0267 0268 #include "sambamount.moc" 0269