Commit 0d90514b authored by Tomi Leppänen's avatar Tomi Leppänen

[nemo-systemsettings] Add methods to modify groups to UserModel. Contributes to JB#49566

Add new UserModel methods hasGroup, addGroups and removeGroups to modify
user's groups. hasGroup is basically the same as AccessControl.hasGroup
but uses model index instead of uid. addGroups and removeGroups use
user-managerd to change groups.
Signed-off-by: Tomi Leppänen's avatarTomi Leppänen <tomi.leppanen@jolla.com>
parent 053b423c
......@@ -11,7 +11,7 @@ Requires: connman
Requires: mce >= 1.83.0
Requires: libsailfishkeyprovider >= 0.0.14
Requires: connman-qt5 >= 1.2.21
Requires: user-managerd >= 0.3.0
Requires: user-managerd >= 0.4.0
Requires(post): coreutils
BuildRequires: pkgconfig(Qt5Qml)
BuildRequires: pkgconfig(Qt5SystemInfo)
......
......@@ -7,7 +7,7 @@ QT -= gui
CONFIG += c++11 hide_symbols link_pkgconfig
PKGCONFIG += profile mlite5 mce timed-qt5 libshadowutils blkid libcrypto nemomodels-qt5 libsailfishkeyprovider connman-qt5 glib-2.0
PKGCONFIG += ssu-sysinfo nemodbus packagekitqt5 libsystemd sailfishusermanager
PKGCONFIG += ssu-sysinfo nemodbus packagekitqt5 libsystemd sailfishusermanager sailfishaccesscontrol
system(qdbusxml2cpp -p mceiface.h:mceiface.cpp mce.xml)
......
......@@ -41,9 +41,10 @@
#include <QDBusServiceWatcher>
#include <QString>
#include <functional>
#include <grp.h>
#include <sailfishaccesscontrol.h>
#include <sailfishusermanagerinterface.h>
#include <sys/types.h>
#include <grp.h>
namespace {
const auto UserManagerService = QStringLiteral(SAILFISH_USERMANAGER_DBUS_INTERFACE);
......@@ -59,6 +60,9 @@ const QHash<const QString, int> errorTypeMap = {
{ QStringLiteral(SailfishUserManagerErrorUserModifyFailed), UserModel::UserModifyFailed },
{ QStringLiteral(SailfishUserManagerErrorUserRemoveFailed), UserModel::UserRemoveFailed },
{ QStringLiteral(SailfishUserManagerErrorGetUidFailed), UserModel::GetUidFailed },
{ QStringLiteral(SailfishUserManagerErrorUserNotFound), UserModel::UserNotFound },
{ QStringLiteral(SailfishUserManagerErrorAddToGroupFailed), UserModel::AddToGroupFailed },
{ QStringLiteral(SailfishUserManagerErrorRemoveFromGroupFailed), UserModel::RemoveFromGroupFailed },
};
int getErrorType(QDBusError &error)
......@@ -282,6 +286,50 @@ UserInfo * UserModel::getCurrentUser() const
return new UserInfo();
}
bool UserModel::hasGroup(int row, const QString &group) const
{
if (row < 0 || row >= m_users.count())
return false;
auto user = m_users.at(row);
if (!user.isValid())
return false;
return sailfish_access_control_hasgroup(user.uid(), group.toUtf8().constData());
}
void UserModel::addGroups(int row, const QStringList &groups)
{
if (row < 0 || row >= m_users.count())
return;
auto user = m_users.at(row);
if (!user.isValid())
return;
createInterface();
auto call = m_dBusInterface->asyncCall(QStringLiteral("addToGroups"), (uint)user.uid(), groups);
auto *watcher = new QDBusPendingCallWatcher(call, this);
connect(watcher, &QDBusPendingCallWatcher::finished,
this, std::bind(&UserModel::addToGroupsFinished, this, std::placeholders::_1, row));
}
void UserModel::removeGroups(int row, const QStringList &groups)
{
if (row < 0 || row >= m_users.count())
return;
auto user = m_users.at(row);
if (!user.isValid())
return;
createInterface();
auto call = m_dBusInterface->asyncCall(QStringLiteral("removeFromGroups"), (uint)user.uid(), groups);
auto *watcher = new QDBusPendingCallWatcher(call, this);
connect(watcher, &QDBusPendingCallWatcher::finished,
this, std::bind(&UserModel::removeFromGroupsFinished, this, std::placeholders::_1, row));
}
void UserModel::onUserAdded(const SailfishUserManagerEntry &entry)
{
if (m_uidsToRows.contains(entry.uid))
......@@ -411,6 +459,32 @@ void UserModel::setCurrentUserFinished(QDBusPendingCallWatcher *call, int row)
call->deleteLater();
}
void UserModel::addToGroupsFinished(QDBusPendingCallWatcher *call, int row)
{
QDBusPendingReply<void> reply = *call;
if (reply.isError()) {
auto error = reply.error();
emit addGroupsFailed(row, getErrorType(error));
qCWarning(lcUsersLog) << "Adding user to groups failed:" << error;
} else {
emit userGroupsChanged(row);
}
call->deleteLater();
}
void UserModel::removeFromGroupsFinished(QDBusPendingCallWatcher *call, int row)
{
QDBusPendingReply<void> reply = *call;
if (reply.isError()) {
auto error = reply.error();
emit removeGroupsFailed(row, getErrorType(error));
qCWarning(lcUsersLog) << "Adding user to groups failed:" << error;
} else {
emit userGroupsChanged(row);
}
call->deleteLater();
}
void UserModel::createInterface()
{
if (!m_dBusInterface) {
......
......@@ -79,6 +79,9 @@ public:
UserModifyFailed,
UserRemoveFailed,
GetUidFailed,
UserNotFound,
AddToGroupFailed,
RemoveFromGroupFailed,
};
Q_ENUM(ErrorType)
......@@ -94,18 +97,27 @@ public:
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
// Methods to modify users
Q_INVOKABLE void createUser();
Q_INVOKABLE void removeUser(int row);
Q_INVOKABLE void reset(int row);
Q_INVOKABLE void setCurrentUser(int row);
Q_INVOKABLE UserInfo * getCurrentUser() const;
// Methods to modify user's groups
Q_INVOKABLE bool hasGroup(int row, const QString &group) const;
Q_INVOKABLE void addGroups(int row, const QStringList &groups);
Q_INVOKABLE void removeGroups(int row, const QStringList &groups);
signals:
void placeholderChanged();
void userGroupsChanged(int row);
void userAddFailed(int error);
void userModifyFailed(int row, int error);
void userRemoveFailed(int row, int error);
void setCurrentUserFailed(int row, int error);
void addGroupsFailed(int row, int error);
void removeGroupsFailed(int row, int error);
private slots:
void onUserAdded(const SailfishUserManagerEntry &entry);
......@@ -118,6 +130,8 @@ private slots:
void userModifyFinished(QDBusPendingCallWatcher *call, int row);
void userRemoveFinished(QDBusPendingCallWatcher *call, int row);
void setCurrentUserFinished(QDBusPendingCallWatcher *call, int row);
void addToGroupsFinished(QDBusPendingCallWatcher *call, int row);
void removeFromGroupsFinished(QDBusPendingCallWatcher *call, int row);
void createInterface();
void destroyInterface();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment