File indexing completed on 2025-01-05 04:35:36

0001 /*
0002     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0003     SPDX-FileCopyrightText: 2020 Harald Sitter <sitter@kde.org>
0004 */
0005 
0006 #include "groupmanager.h"
0007 
0008 #include <QFileInfo>
0009 #include <QProcess>
0010 
0011 #include <KUser>
0012 #include <KAuth/Action>
0013 #include <KAuth/ExecuteJob>
0014 #include <KLocalizedString>
0015 
0016 GroupManager::GroupManager(QObject *parent)
0017     : QObject(parent)
0018 {
0019     metaObject()->invokeMethod(this, [this] {
0020         auto proc = new QProcess;
0021         proc->setProgram(QStringLiteral("testparm"));
0022         proc->setArguments({QStringLiteral("--debuglevel=0"),
0023                             QStringLiteral("--suppress-prompt"),
0024                             QStringLiteral("--verbose"),
0025                             QStringLiteral("--parameter-name"),
0026                             QStringLiteral("usershare path")});
0027         connect(proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this, proc] {
0028             proc->deleteLater();
0029             const QString path = QString::fromUtf8(proc->readAllStandardOutput().simplified());
0030             QFileInfo info(path);
0031             m_targetGroup = info.group();
0032             m_user = KUser().loginName();
0033             const QStringList groups = KUser(m_user).groupNames();
0034 
0035             if (path.isEmpty()) {
0036                 m_errorText = xi18nc("@info:status", "Your Samba installation appears to be broken.");
0037                 Q_EMIT errorTextChanged();
0038                 const auto err = proc->readAllStandardError().trimmed();
0039                 if (err.isEmpty()) {
0040                     m_errorExplanation = xi18nc("@info:status", "This error is caused by your distribution not setting up Samba sharing properly. Please file a bug with your distribution or check your distribution's documentation on setting up Samba sharing.");
0041                 } else {
0042                     m_errorExplanation = xi18nc("@info:status", "This error is caused by your distribution not setting up Samba sharing properly. Please file a bug with your distribution or check your distribution's documentation on setting up Samba sharing. Error:<nl/><message>%1</message>", QString::fromUtf8(err));
0043                 }
0044                 Q_EMIT errorExplanationChanged();
0045             }
0046 
0047             // Check to see if the path where user shares will be exported exists
0048             else if (!info.exists()) {
0049                 m_errorText = xi18nc("@info:status", "This folder can't be shared because <filename>%1</filename> does not exist.", path);
0050                 Q_EMIT errorTextChanged();
0051                 m_errorExplanation = xi18nc("@info:status", "This error is caused by your distribution not setting up Samba sharing properly. You can fix it yourself by creating that folder manually. Then close and re-open this window.");
0052                 Q_EMIT errorExplanationChanged();
0053                 // TODO: define a helpfulAction that creates the folder
0054             }
0055 
0056             // Now see if the user is a member of the group
0057             else if (!groups.contains(m_targetGroup)) {
0058                 m_errorText = xi18nc("@info:status", "This folder can't be shared because your user account isn't a member of the <resource>%1</resource> group.", m_targetGroup);
0059                 Q_EMIT errorTextChanged();
0060                 m_errorExplanation = xi18nc("@info:status", "You can fix this by making your user a member of that group. Then restart the system.");
0061                 Q_EMIT errorExplanationChanged();
0062                 m_helpfulActionIcon = QStringLiteral("resource-group-new");
0063                 Q_EMIT helpfulActionIconChanged();
0064                 m_helpfulActionText = i18nc("action@button makes user a member of the samba share group", "Make me a Group Member");
0065                 Q_EMIT helpfulActionTextChanged();
0066                 m_helpfulAction = HelpfulAction::AddUserToGroup;
0067                 m_hasHelpfulAction = true;
0068                 Q_EMIT hasHelpfulActionChanged();
0069             }
0070 
0071             // Now see if it's writable by the user
0072             else if (!info.isWritable()) {
0073                 m_errorText = xi18nc("@info:status", "This folder can't be shared because your user account doesn't have permission to write into <filename>%1</filename>.", path);
0074                 Q_EMIT errorTextChanged();
0075                 m_errorExplanation = xi18nc("@info:status", "You can fix this by ensuring that the <resource>%1</resource> group has write permission for <filename>%2</filename>. Then close and re-open this window.",  m_targetGroup, path);
0076                 Q_EMIT errorExplanationChanged();
0077                 // TODO: define a helpfulAction that adds group write permission to the folder
0078             }
0079 
0080             m_ready = true;
0081             Q_EMIT isReadyChanged();
0082 
0083             // If we got here without hitting any errors, everything should work
0084         });
0085         proc->start();
0086     });
0087 }
0088 
0089 void GroupManager::performHelpfulAction()
0090 {
0091     switch (m_helpfulAction) {
0092         case HelpfulAction::AddUserToGroup: {
0093             const QString user = m_user;
0094             const QString group = m_targetGroup;
0095             Q_ASSERT(!user.isEmpty());
0096             Q_ASSERT(!group.isEmpty());
0097             auto action = KAuth::Action(QStringLiteral("org.kde.filesharing.samba.addtogroup"));
0098             action.setHelperId(QStringLiteral("org.kde.filesharing.samba"));
0099             action.addArgument(QStringLiteral("group"), group);
0100             action.setDetailsV2({{KAuth::Action::AuthDetail::DetailMessage,
0101                                 xi18nc("@label kauth action description %1 is a username %2 a group name",
0102                                         "Adding user <resource>%1</resource> to group <resource>%2</resource> so they may configure Samba user shares",
0103                                         user,
0104                                         group) }
0105             });
0106             KAuth::ExecuteJob *job = action.execute();
0107             connect(job, &KAuth::ExecuteJob::result, this, [this, job, user, group] {
0108                 job->deleteLater();
0109                 if (job->error() != KAuth::ExecuteJob::NoError) {
0110                     QString helpfulActionErrorText = job->errorString();
0111                     if (helpfulActionErrorText.isEmpty()) {
0112                         // unknown error :(
0113                         helpfulActionErrorText = xi18nc("@info", "Failed to make user <resource>%1</resource> a member of group <resource>%2</resource>", user, group);
0114                     }
0115                     Q_EMIT helpfulActionError(helpfulActionErrorText);
0116                     return;
0117                 }
0118                 Q_EMIT needsReboot();
0119             });
0120             job->start();
0121             break;
0122         }
0123         case HelpfulAction::None:
0124             // Do nothing
0125             break;
0126         // no Default so we have to explicitly handle new enums in the future
0127     }
0128 }