diff --git a/rpm/nemo-qml-plugin-systemsettings.spec b/rpm/nemo-qml-plugin-systemsettings.spec index 73f34e1..93fe92f 100644 --- a/rpm/nemo-qml-plugin-systemsettings.spec +++ b/rpm/nemo-qml-plugin-systemsettings.spec @@ -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) diff --git a/src/src.pro b/src/src.pro index ee18be2..128d229 100644 --- a/src/src.pro +++ b/src/src.pro @@ -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) diff --git a/src/usermodel.cpp b/src/usermodel.cpp index 887b3d9..6f16c6a 100644 --- a/src/usermodel.cpp +++ b/src/usermodel.cpp @@ -41,9 +41,10 @@ #include #include #include +#include +#include #include #include -#include namespace { const auto UserManagerService = QStringLiteral(SAILFISH_USERMANAGER_DBUS_INTERFACE); @@ -59,6 +60,9 @@ const QHash 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 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 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) { diff --git a/src/usermodel.h b/src/usermodel.h index 8e45fd0..a7da152 100644 --- a/src/usermodel.h +++ b/src/usermodel.h @@ -79,6 +79,9 @@ class SYSTEMSETTINGS_EXPORT UserModel: public QAbstractListModel UserModifyFailed, UserRemoveFailed, GetUidFailed, + UserNotFound, + AddToGroupFailed, + RemoveFromGroupFailed, }; Q_ENUM(ErrorType) @@ -94,18 +97,27 @@ class SYSTEMSETTINGS_EXPORT UserModel: public QAbstractListModel 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();