From f679c8abab32fc575e68d9c4fd2258ce69d27146 Mon Sep 17 00:00:00 2001 From: vasilito Date: Sat, 1 Aug 2026 04:46:06 +0300 Subject: [PATCH] polkit-qt6: vendor as full-fork recipe (path=source, patches baked) --- local/recipes/libs/polkit-qt6/recipe.toml | 8 +- .../recipes/libs/polkit-qt6/source/.gitignore | 29 + .../libs/polkit-qt6/source/.gitlab-ci.yml | 10 + .../libs/polkit-qt6/source/.kde-ci.yml | 2 + .../polkit-qt6/source/.redbear-src-version | 1 + local/recipes/libs/polkit-qt6/source/AUTHORS | 9 + .../libs/polkit-qt6/source/CMakeLists.txt | 195 ++++ local/recipes/libs/polkit-qt6/source/INSTALL | 26 + .../source/LICENSES/BSD-3-Clause.txt | 26 + .../source/LICENSES/GPL-2.0-or-later.txt | 311 ++++++ .../source/LICENSES/LGPL-2.0-or-later.txt | 444 +++++++++ .../libs/polkit-qt6/source/Mainpage.dox | 107 +++ .../source/PolkitQt-1Config.cmake.in | 55 ++ local/recipes/libs/polkit-qt6/source/README | 23 + .../libs/polkit-qt6/source/README.porting | 25 + local/recipes/libs/polkit-qt6/source/TODO | 11 + .../polkit-qt6/source/agent/CMakeLists.txt | 39 + .../source/agent/listeneradapter.cpp | 135 +++ .../source/agent/listeneradapter_p.h | 70 ++ .../source/agent/polkitqt1-agent-listener.cpp | 109 +++ .../source/agent/polkitqt1-agent-listener.h | 147 +++ .../source/agent/polkitqt1-agent-session.cpp | 157 +++ .../source/agent/polkitqt1-agent-session.h | 168 ++++ .../source/agent/polkitqtlistener.cpp | 135 +++ .../source/agent/polkitqtlistener_p.h | 35 + .../polkit-qt6/source/core/CMakeLists.txt | 43 + .../core/polkitqt1-actiondescription.cpp | 133 +++ .../source/core/polkitqt1-actiondescription.h | 136 +++ .../source/core/polkitqt1-authority.cpp | 902 ++++++++++++++++++ .../source/core/polkitqt1-authority.h | 550 +++++++++++ .../source/core/polkitqt1-details.cpp | 94 ++ .../source/core/polkitqt1-details.h | 89 ++ .../source/core/polkitqt1-identity.cpp | 212 ++++ .../source/core/polkitqt1-identity.h | 198 ++++ .../source/core/polkitqt1-subject.cpp | 213 +++++ .../source/core/polkitqt1-subject.h | 276 ++++++ .../core/polkitqt1-temporaryauthorization.cpp | 103 ++ .../core/polkitqt1-temporaryauthorization.h | 111 +++ .../polkit-qt6/source/examples/CMakeLists.txt | 63 ++ .../polkit-qt6/source/examples/PkExample.cpp | 227 +++++ .../polkit-qt6/source/examples/PkExample.h | 28 + .../polkit-qt6/source/examples/PkExample.ui | 234 +++++ .../source/examples/PkExampleHelper.cpp | 97 ++ .../source/examples/PkExampleHelper.h | 29 + .../source/examples/agent/CMakeLists.txt | 16 + .../source/examples/agent/klistener.cpp | 88 ++ .../source/examples/agent/klistener.h | 43 + .../polkit-qt6/source/examples/agent/main.cpp | 17 + .../source/examples/agent/pkagentexample.cpp | 15 + .../source/examples/agent/pkagentexample.h | 28 + .../examples/icons/action-locked-default.png | Bin 0 -> 1686 bytes .../source/examples/icons/action-locked.png | Bin 0 -> 1052 bytes .../source/examples/icons/action-unlocked.png | Bin 0 -> 4744 bytes .../source/examples/icons/custom-no.png | Bin 0 -> 1650 bytes .../source/examples/icons/custom-yes.png | Bin 0 -> 1628 bytes .../source/examples/icons/icons.qrc | 9 + .../libs/polkit-qt6/source/examples/main.cpp | 18 + .../polkit-qt6/source/examples/mainHelper.cpp | 14 + .../examples/org.qt.policykit.examples.conf | 20 + .../examples/org.qt.policykit.examples.policy | 81 ++ .../org.qt.policykit.examples.policy.in | 85 ++ .../org.qt.policykit.examples.service.in | 5 + .../examples/org.qt.policykit.examples.xml | 11 + .../libs/polkit-qt6/source/gui/CMakeLists.txt | 38 + .../source/gui/polkitqt1-gui-action.cpp | 502 ++++++++++ .../source/gui/polkitqt1-gui-action.h | 291 ++++++ .../source/gui/polkitqt1-gui-actionbutton.cpp | 153 +++ .../source/gui/polkitqt1-gui-actionbutton.h | 131 +++ .../source/gui/polkitqt1-gui-actionbutton_p.h | 37 + .../gui/polkitqt1-gui-actionbuttons.cpp | 58 ++ .../source/gui/polkitqt1-gui-actionbuttons.h | 101 ++ .../gui/polkitqt1-gui-actionbuttons_p.h | 23 + .../includes/PolkitQt1/ActionDescription | 1 + .../source/includes/PolkitQt1/Agent/Listener | 1 + .../source/includes/PolkitQt1/Agent/Session | 1 + .../source/includes/PolkitQt1/Authority | 1 + .../source/includes/PolkitQt1/Details | 1 + .../source/includes/PolkitQt1/Gui/Action | 1 + .../includes/PolkitQt1/Gui/ActionButton | 1 + .../includes/PolkitQt1/Gui/ActionButtons | 1 + .../source/includes/PolkitQt1/Identity | 1 + .../source/includes/PolkitQt1/Subject | 1 + .../includes/PolkitQt1/TemporaryAuthorization | 1 + .../libs/polkit-qt6/source/metainfo.yaml | 21 + .../polkit-qt6/source/polkit-qt-1.pc.cmake | 11 + .../source/polkit-qt-agent-1.pc.cmake | 11 + .../source/polkit-qt-core-1.pc.cmake | 11 + .../source/polkit-qt-gui-1.pc.cmake | 11 + .../polkit-qt6/source/polkit-qt5-1.pc.cmake | 11 + .../source/polkit-qt5-agent-1.pc.cmake | 11 + .../source/polkit-qt5-core-1.pc.cmake | 11 + .../source/polkit-qt5-gui-1.pc.cmake | 11 + .../polkit-qt6/source/polkit-qt6-1.pc.cmake | 11 + .../source/polkit-qt6-agent-1.pc.cmake | 11 + .../source/polkit-qt6-core-1.pc.cmake | 11 + .../source/polkit-qt6-gui-1.pc.cmake | 11 + .../source/polkitqt1-config.h.cmake | 1 + .../source/polkitqt1-version.h.cmake | 53 + .../polkit-qt6/source/test/CMakeLists.txt | 16 + .../libs/polkit-qt6/source/test/test.cpp | 237 +++++ .../libs/polkit-qt6/source/test/test.h | 20 + 101 files changed, 8288 insertions(+), 2 deletions(-) create mode 100644 local/recipes/libs/polkit-qt6/source/.gitignore create mode 100644 local/recipes/libs/polkit-qt6/source/.gitlab-ci.yml create mode 100644 local/recipes/libs/polkit-qt6/source/.kde-ci.yml create mode 100644 local/recipes/libs/polkit-qt6/source/.redbear-src-version create mode 100644 local/recipes/libs/polkit-qt6/source/AUTHORS create mode 100644 local/recipes/libs/polkit-qt6/source/CMakeLists.txt create mode 100644 local/recipes/libs/polkit-qt6/source/INSTALL create mode 100644 local/recipes/libs/polkit-qt6/source/LICENSES/BSD-3-Clause.txt create mode 100644 local/recipes/libs/polkit-qt6/source/LICENSES/GPL-2.0-or-later.txt create mode 100644 local/recipes/libs/polkit-qt6/source/LICENSES/LGPL-2.0-or-later.txt create mode 100644 local/recipes/libs/polkit-qt6/source/Mainpage.dox create mode 100644 local/recipes/libs/polkit-qt6/source/PolkitQt-1Config.cmake.in create mode 100644 local/recipes/libs/polkit-qt6/source/README create mode 100644 local/recipes/libs/polkit-qt6/source/README.porting create mode 100644 local/recipes/libs/polkit-qt6/source/TODO create mode 100644 local/recipes/libs/polkit-qt6/source/agent/CMakeLists.txt create mode 100644 local/recipes/libs/polkit-qt6/source/agent/listeneradapter.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/agent/listeneradapter_p.h create mode 100644 local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-listener.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-listener.h create mode 100644 local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-session.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-session.h create mode 100644 local/recipes/libs/polkit-qt6/source/agent/polkitqtlistener.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/agent/polkitqtlistener_p.h create mode 100644 local/recipes/libs/polkit-qt6/source/core/CMakeLists.txt create mode 100644 local/recipes/libs/polkit-qt6/source/core/polkitqt1-actiondescription.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/core/polkitqt1-actiondescription.h create mode 100644 local/recipes/libs/polkit-qt6/source/core/polkitqt1-authority.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/core/polkitqt1-authority.h create mode 100644 local/recipes/libs/polkit-qt6/source/core/polkitqt1-details.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/core/polkitqt1-details.h create mode 100644 local/recipes/libs/polkit-qt6/source/core/polkitqt1-identity.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/core/polkitqt1-identity.h create mode 100644 local/recipes/libs/polkit-qt6/source/core/polkitqt1-subject.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/core/polkitqt1-subject.h create mode 100644 local/recipes/libs/polkit-qt6/source/core/polkitqt1-temporaryauthorization.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/core/polkitqt1-temporaryauthorization.h create mode 100644 local/recipes/libs/polkit-qt6/source/examples/CMakeLists.txt create mode 100644 local/recipes/libs/polkit-qt6/source/examples/PkExample.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/examples/PkExample.h create mode 100644 local/recipes/libs/polkit-qt6/source/examples/PkExample.ui create mode 100644 local/recipes/libs/polkit-qt6/source/examples/PkExampleHelper.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/examples/PkExampleHelper.h create mode 100644 local/recipes/libs/polkit-qt6/source/examples/agent/CMakeLists.txt create mode 100644 local/recipes/libs/polkit-qt6/source/examples/agent/klistener.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/examples/agent/klistener.h create mode 100644 local/recipes/libs/polkit-qt6/source/examples/agent/main.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/examples/agent/pkagentexample.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/examples/agent/pkagentexample.h create mode 100644 local/recipes/libs/polkit-qt6/source/examples/icons/action-locked-default.png create mode 100644 local/recipes/libs/polkit-qt6/source/examples/icons/action-locked.png create mode 100644 local/recipes/libs/polkit-qt6/source/examples/icons/action-unlocked.png create mode 100644 local/recipes/libs/polkit-qt6/source/examples/icons/custom-no.png create mode 100644 local/recipes/libs/polkit-qt6/source/examples/icons/custom-yes.png create mode 100644 local/recipes/libs/polkit-qt6/source/examples/icons/icons.qrc create mode 100644 local/recipes/libs/polkit-qt6/source/examples/main.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/examples/mainHelper.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.conf create mode 100644 local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.policy create mode 100644 local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.policy.in create mode 100644 local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.service.in create mode 100644 local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.xml create mode 100644 local/recipes/libs/polkit-qt6/source/gui/CMakeLists.txt create mode 100644 local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-action.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-action.h create mode 100644 local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbutton.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbutton.h create mode 100644 local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbutton_p.h create mode 100644 local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbuttons.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbuttons.h create mode 100644 local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbuttons_p.h create mode 100644 local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/ActionDescription create mode 100644 local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Agent/Listener create mode 100644 local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Agent/Session create mode 100644 local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Authority create mode 100644 local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Details create mode 100644 local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Gui/Action create mode 100644 local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Gui/ActionButton create mode 100644 local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Gui/ActionButtons create mode 100644 local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Identity create mode 100644 local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Subject create mode 100644 local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/TemporaryAuthorization create mode 100644 local/recipes/libs/polkit-qt6/source/metainfo.yaml create mode 100644 local/recipes/libs/polkit-qt6/source/polkit-qt-1.pc.cmake create mode 100644 local/recipes/libs/polkit-qt6/source/polkit-qt-agent-1.pc.cmake create mode 100644 local/recipes/libs/polkit-qt6/source/polkit-qt-core-1.pc.cmake create mode 100644 local/recipes/libs/polkit-qt6/source/polkit-qt-gui-1.pc.cmake create mode 100644 local/recipes/libs/polkit-qt6/source/polkit-qt5-1.pc.cmake create mode 100644 local/recipes/libs/polkit-qt6/source/polkit-qt5-agent-1.pc.cmake create mode 100644 local/recipes/libs/polkit-qt6/source/polkit-qt5-core-1.pc.cmake create mode 100644 local/recipes/libs/polkit-qt6/source/polkit-qt5-gui-1.pc.cmake create mode 100644 local/recipes/libs/polkit-qt6/source/polkit-qt6-1.pc.cmake create mode 100644 local/recipes/libs/polkit-qt6/source/polkit-qt6-agent-1.pc.cmake create mode 100644 local/recipes/libs/polkit-qt6/source/polkit-qt6-core-1.pc.cmake create mode 100644 local/recipes/libs/polkit-qt6/source/polkit-qt6-gui-1.pc.cmake create mode 100644 local/recipes/libs/polkit-qt6/source/polkitqt1-config.h.cmake create mode 100644 local/recipes/libs/polkit-qt6/source/polkitqt1-version.h.cmake create mode 100644 local/recipes/libs/polkit-qt6/source/test/CMakeLists.txt create mode 100644 local/recipes/libs/polkit-qt6/source/test/test.cpp create mode 100644 local/recipes/libs/polkit-qt6/source/test/test.h diff --git a/local/recipes/libs/polkit-qt6/recipe.toml b/local/recipes/libs/polkit-qt6/recipe.toml index dee6eb29be..9841bfafac 100644 --- a/local/recipes/libs/polkit-qt6/recipe.toml +++ b/local/recipes/libs/polkit-qt6/recipe.toml @@ -8,8 +8,12 @@ version = "0.3.1" # polkit-1 backend (delegates to the redbear-polkit D-Bus daemon for # real authorization) instead of the prior FAKE backend (always denies). [source] -git = "https://invent.kde.org/libraries/polkit-qt-1.git" -branch = "master" +# Vendored local fork (full-fork model): builds from the committed source/ +# tree (offline, reproducible). source/ = pristine upstream + the patches below +# BAKED IN. .patch files kept tracked so a version bump can re-apply them via +# sync-recipe-source.sh. +# upstream: https://invent.kde.org/libraries/polkit-qt-1.git +path = "source" [build] template = "custom" diff --git a/local/recipes/libs/polkit-qt6/source/.gitignore b/local/recipes/libs/polkit-qt6/source/.gitignore new file mode 100644 index 0000000000..e9b99b7977 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/.gitignore @@ -0,0 +1,29 @@ +*~ +build/ +apidocs/ +Doxyfile +*.patch + +# CMake +CMakeCache.txt +CMakeFiles +cmake_install.cmake +CMakeLists.txt.user +CMakeLists.txt.user.* + +# QtCreator +qtcreator-build + +# Misc +*.moc +moc_* +ui_* +Makefile + +# LSP and IDEs +/.clang-format +/compile_commands.json +.clangd +.cache +.idea +.vscode diff --git a/local/recipes/libs/polkit-qt6/source/.gitlab-ci.yml b/local/recipes/libs/polkit-qt6/source/.gitlab-ci.yml new file mode 100644 index 0000000000..92c4a3f3c1 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/.gitlab-ci.yml @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: None +# SPDX-License-Identifier: CC0-1.0 + +include: + - project: sysadmin/ci-utilities + file: + - /gitlab-templates/linux-qt6.yml + - /gitlab-templates/linux-qt6-next.yml + - /gitlab-templates/linux.yml + - /gitlab-templates/freebsd-qt6.yml diff --git a/local/recipes/libs/polkit-qt6/source/.kde-ci.yml b/local/recipes/libs/polkit-qt6/source/.kde-ci.yml new file mode 100644 index 0000000000..83e6edb729 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/.kde-ci.yml @@ -0,0 +1,2 @@ +Options: + cmake-options: '-DBUILD_EXAMPLES=ON' diff --git a/local/recipes/libs/polkit-qt6/source/.redbear-src-version b/local/recipes/libs/polkit-qt6/source/.redbear-src-version new file mode 100644 index 0000000000..2b575dd3fe --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/.redbear-src-version @@ -0,0 +1 @@ +polkit-qt-1.git diff --git a/local/recipes/libs/polkit-qt6/source/AUTHORS b/local/recipes/libs/polkit-qt6/source/AUTHORS new file mode 100644 index 0000000000..172f2ad393 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/AUTHORS @@ -0,0 +1,9 @@ +Main Authors: +- Daniel Nicoletti +- Dario Freddi +- Jaroslav Reznik + +Contributors: +- Pino Toscano +- Lukas Tinkl +- Radek Novacek \ No newline at end of file diff --git a/local/recipes/libs/polkit-qt6/source/CMakeLists.txt b/local/recipes/libs/polkit-qt6/source/CMakeLists.txt new file mode 100644 index 0000000000..5d49d9edcf --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/CMakeLists.txt @@ -0,0 +1,195 @@ +cmake_minimum_required(VERSION 3.11) + +## Polkit Qt Library +project("PolkitQt-1") + +set(CMAKE_AUTOMOC TRUE) +set(CMAKE_AUTOUIC TRUE) +set(CMAKE_AUTORCC TRUE) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH}) + +# Used to create CMake config files +include(CMakePackageConfigHelpers) + +# Used to generate export headers +include(GenerateExportHeader) + +# Used to set installation paths +include(GNUInstallDirs) + +include(FeatureSummary) + +set(REQUIRED_QT_VERSION 5.5.0) +set(CMAKE_CXX_STANDARD 11) + +option(BUILD_WITH_QT6 "Build against Qt 6" OFF) + +if (NOT DEFINED QT_MAJOR_VERSION) + if (BUILD_WITH_QT6) + set(QT_MAJOR_VERSION 6) + else() + set(QT_MAJOR_VERSION 5) + endif() +endif() + +find_package(Qt${QT_MAJOR_VERSION} ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS Core DBus Widgets) + +find_package(PkgConfig REQUIRED) + +set(POLKITQT-1_PCNAME "polkit-qt${QT_MAJOR_VERSION}-1") +set(POLKITQT-1_CORE_PCNAME "polkit-qt${QT_MAJOR_VERSION}-core-1") +set(POLKITQT-1_GUI_PCNAME "polkit-qt${QT_MAJOR_VERSION}-gui-1") +set(POLKITQT-1_AGENT_PCNAME "polkit-qt${QT_MAJOR_VERSION}-agent-1") +set(POLKITQT-1_CAMEL_NAME "PolkitQt${QT_MAJOR_VERSION}-1") +set(POLKITQT-1_EXAMPLE "polkit-example-qt${QT_MAJOR_VERSION}") +set(POLKITQT-1_EXAMPLE_HELPER "polkit-example-helper-qt${QT_MAJOR_VERSION}") +set(POLKITQT-1_AGENT_EXAMPLE "polkit-agent-example-qt${QT_MAJOR_VERSION}") +set(POLKITQT-1_INCLUDE_PATH "polkit-qt${QT_MAJOR_VERSION}-1") + +pkg_check_modules(POLKIT_GOBJECT polkit-gobject-1 REQUIRED IMPORTED_TARGET) +pkg_check_modules(POLKIT_AGENT polkit-agent-1 REQUIRED IMPORTED_TARGET) +pkg_check_modules(GLIB2 glib-2.0>=2.36 REQUIRED IMPORTED_TARGET) +pkg_check_modules(GOBJECT gobject-2.0 REQUIRED IMPORTED_TARGET) + +add_definitions(-DQT_NO_KEYWORDS) + +include (CheckFunctionExists) + +# Check for older polkit +set(CMAKE_REQUIRED_INCLUDES ${POLKIT_GOBJECT_INCLUDE_DIRS} ${POLKIT_AGENT_INCLUDE_DIRS}) +set(CMAKE_REQUIRED_LIBRARIES ${POLKIT_GOBJECT_LIBRARIES} ${POLKIT_AGENT_LIBRARIES}) +check_function_exists(polkit_agent_listener_register HAVE_POLKIT_AGENT_LISTENER_REGISTER) +check_function_exists(polkit_authority_get_sync HAVE_POLKIT_AUTHORITY_GET_SYNC) +check_function_exists(polkit_system_bus_name_get_user_sync HAVE_POLKIT_SYSTEM_BUS_NAME_GET_USER_SYNC) + +if (NOT HAVE_POLKIT_AGENT_LISTENER_REGISTER OR NOT HAVE_POLKIT_AUTHORITY_GET_SYNC) + message(STATUS "You have an older polkit-1 version: Polkit-Qt-1 will be built in compatibility mode") + add_definitions(-DPOLKIT_QT_1_COMPATIBILITY_MODE) +endif (NOT HAVE_POLKIT_AGENT_LISTENER_REGISTER OR NOT HAVE_POLKIT_AUTHORITY_GET_SYNC) + +option(USE_COMMON_CMAKE_PACKAGE_CONFIG_DIR "Prefer to install the Config.cmake files to lib/cmake/ instead of lib//cmake" TRUE) + +set(POLKITQT-1_VERSION_MAJOR "0") +set(POLKITQT-1_VERSION_MINOR "201") +set(POLKITQT-1_VERSION_PATCH "1") +set(POLKITQT-1_VERSION_STRING + "${POLKITQT-1_VERSION_MAJOR}.${POLKITQT-1_VERSION_MINOR}.${POLKITQT-1_VERSION_PATCH}") + +# The SONUMBER of the polkit-qt-1 libraries +set(POLKITQT-1_ABI_VERSION 1) +# The version number of the polkit-qt-1 libraries +set(POLKITQT-1_LIBRARY_VERSION "${POLKITQT-1_ABI_VERSION}.${POLKITQT-1_VERSION_MINOR}.${POLKITQT-1_VERSION_PATCH}") +set(POLKITQT-1_LIB_NAMESPACE ${POLKITQT-1_CAMEL_NAME}) + +configure_file(polkitqt1-version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/core/polkitqt1-version.h) +configure_file(polkitqt1-config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/core/polkitqt1-config.h) + +install(FILES + gui/polkitqt1-gui-action.h + gui/polkitqt1-gui-actionbutton.h + gui/polkitqt1-gui-actionbuttons.h + + core/polkitqt1-authority.h + core/polkitqt1-details.h + core/polkitqt1-identity.h + core/polkitqt1-subject.h + core/polkitqt1-temporaryauthorization.h + core/polkitqt1-actiondescription.h + + agent/polkitqt1-agent-listener.h + agent/polkitqt1-agent-session.h + + ${CMAKE_CURRENT_BINARY_DIR}/core/polkitqt1-version.h + + ${CMAKE_CURRENT_BINARY_DIR}/core/polkitqt1-core-export.h + ${CMAKE_CURRENT_BINARY_DIR}/gui/polkitqt1-gui-export.h + ${CMAKE_CURRENT_BINARY_DIR}/agent/polkitqt1-agent-export.h + + DESTINATION + ${CMAKE_INSTALL_INCLUDEDIR}/${POLKITQT-1_INCLUDE_PATH} COMPONENT Devel) + +install(FILES + includes/PolkitQt1/Authority + includes/PolkitQt1/Details + includes/PolkitQt1/Identity + includes/PolkitQt1/Subject + includes/PolkitQt1/TemporaryAuthorization + includes/PolkitQt1/ActionDescription + DESTINATION + ${CMAKE_INSTALL_INCLUDEDIR}/${POLKITQT-1_INCLUDE_PATH}/PolkitQt1 COMPONENT Devel) + +install(FILES + includes/PolkitQt1/Gui/Action + includes/PolkitQt1/Gui/ActionButton + includes/PolkitQt1/Gui/ActionButtons + DESTINATION + ${CMAKE_INSTALL_INCLUDEDIR}/${POLKITQT-1_INCLUDE_PATH}/PolkitQt1/Gui COMPONENT Devel) + +install(FILES + includes/PolkitQt1/Agent/Listener + includes/PolkitQt1/Agent/Session + DESTINATION + ${CMAKE_INSTALL_INCLUDEDIR}/${POLKITQT-1_INCLUDE_PATH}/PolkitQt1/Agent COMPONENT Devel) + +if(NOT WIN32) + # Pkgconfig + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${POLKITQT-1_PCNAME}.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/${POLKITQT-1_PCNAME}.pc @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${POLKITQT-1_PCNAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${POLKITQT-1_CORE_PCNAME}.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/${POLKITQT-1_CORE_PCNAME}.pc + @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${POLKITQT-1_CORE_PCNAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${POLKITQT-1_GUI_PCNAME}.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/${POLKITQT-1_GUI_PCNAME}.pc @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${POLKITQT-1_GUI_PCNAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${POLKITQT-1_AGENT_PCNAME}.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/${POLKITQT-1_AGENT_PCNAME}.pc + @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${POLKITQT-1_AGENT_PCNAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) +endif(NOT WIN32) + + +if(USE_COMMON_CMAKE_PACKAGE_CONFIG_DIR) + set(_PolkitQt-1Config_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${POLKITQT-1_CAMEL_NAME}) +else(USE_COMMON_CMAKE_PACKAGE_CONFIG_DIR) + set(_PolkitQt-1Config_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/${POLKITQT-1_CAMEL_NAME}/cmake) +endif(USE_COMMON_CMAKE_PACKAGE_CONFIG_DIR) + + +# Create the CMake Config files +configure_package_config_file(PolkitQt-1Config.cmake.in + ${CMAKE_BINARY_DIR}/${POLKITQT-1_CAMEL_NAME}Config.cmake + INSTALL_DESTINATION ${_PolkitQt-1Config_INSTALL_DIR} + PATH_VARS CMAKE_INSTALL_LIBDIR CMAKE_INSTALL_INCLUDEDIR +) + +write_basic_package_version_file(${CMAKE_BINARY_DIR}/${POLKITQT-1_CAMEL_NAME}ConfigVersion.cmake + VERSION ${POLKITQT-1_VERSION_STRING} + COMPATIBILITY SameMajorVersion + ) + +install(FILES ${CMAKE_BINARY_DIR}/${POLKITQT-1_CAMEL_NAME}Config.cmake + ${CMAKE_BINARY_DIR}/${POLKITQT-1_CAMEL_NAME}ConfigVersion.cmake + DESTINATION ${_PolkitQt-1Config_INSTALL_DIR} + ) + +install(EXPORT ${POLKITQT-1_CAMEL_NAME}Export FILE ${POLKITQT-1_CAMEL_NAME}Targets.cmake + DESTINATION ${_PolkitQt-1Config_INSTALL_DIR} + NAMESPACE ${POLKITQT-1_LIB_NAMESPACE}::) + +option(BUILD_EXAMPLES "Builds a set of examples for polkit-qt-1" OFF) +if (BUILD_EXAMPLES) + find_package(Qt${QT_MAJOR_VERSION}Xml ${REQUIRED_QT_VERSION} REQUIRED) + add_subdirectory(examples) +endif (BUILD_EXAMPLES) + +option(BUILD_TEST "Builds unit tests for polkit-qt-1" OFF) +if (BUILD_TEST) + find_package(Qt${QT_MAJOR_VERSION}Test ${REQUIRED_QT_VERSION} REQUIRED) + add_subdirectory(test) +endif (BUILD_TEST) + +add_subdirectory(core) +add_subdirectory(gui) +add_subdirectory(agent) + +feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/local/recipes/libs/polkit-qt6/source/INSTALL b/local/recipes/libs/polkit-qt6/source/INSTALL new file mode 100644 index 0000000000..cb38a4c961 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/INSTALL @@ -0,0 +1,26 @@ +Polkit-qt's build system uses cmake. + +So to compile Polkit-qt first create a build dir + + mkdir build + cd build + +then run cmake: + + cmake .. + +(a typical cmake option that is often used is: -DCMAKE_INSTALL_PREFIX=) + +cmake then presents a configuration summary. At this point you may +want to install missing dependencies (if you do, remove the CMakeCache.txt) +and run cmake again. + +Finally build Polkit-qt: + + make + +And install it (in most cases root privileges are required): + + make install + +That's all :) diff --git a/local/recipes/libs/polkit-qt6/source/LICENSES/BSD-3-Clause.txt b/local/recipes/libs/polkit-qt6/source/LICENSES/BSD-3-Clause.txt new file mode 100644 index 0000000000..0741db789e --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/LICENSES/BSD-3-Clause.txt @@ -0,0 +1,26 @@ +Copyright (c) . All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/local/recipes/libs/polkit-qt6/source/LICENSES/GPL-2.0-or-later.txt b/local/recipes/libs/polkit-qt6/source/LICENSES/GPL-2.0-or-later.txt new file mode 100644 index 0000000000..3b6070fcd0 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/LICENSES/GPL-2.0-or-later.txt @@ -0,0 +1,311 @@ +GNU GENERAL PUBLIC LICENSE +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to +most of the Free Software Foundation's software and to any other program whose +authors commit to using it. (Some other Free Software Foundation software +is covered by the GNU Lesser General Public License instead.) You can apply +it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you +wish), that you receive source code or can get it if you want it, that you +can change the software or use pieces of it in new free programs; and that +you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or +for a fee, you must give the recipients all the rights that you have. You +must make sure that they, too, receive or can get the source code. And you +must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If +the software is modified by someone else and passed on, we want its recipients +to know that what they have is not the original, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will individually +obtain patent licenses, in effect making the program proprietary. To prevent +this, we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms +of this General Public License. The "Program", below, refers to any such program +or work, and a "work based on the Program" means either the Program or any +derivative work under copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with modifications and/or translated +into another language. (Hereinafter, translation is included without limitation +in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running the Program +is not restricted, and the output from the Program is covered only if its +contents constitute a work based on the Program (independent of having been +made by running the Program). Whether that is true depends on what the Program +does. + +1. You may copy and distribute verbatim copies of the Program's source code +as you receive it, in any medium, provided that you conspicuously and appropriately +publish on each copy an appropriate copyright notice and disclaimer of warranty; +keep intact all the notices that refer to this License and to the absence +of any warranty; and give any other recipients of the Program a copy of this +License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, +thus forming a work based on the Program, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + +a) You must cause the modified files to carry prominent notices stating that +you changed the files and the date of any change. + +b) You must cause any work that you distribute or publish, that in whole or +in part contains or is derived from the Program or any part thereof, to be +licensed as a whole at no charge to all third parties under the terms of this +License. + +c) If the modified program normally reads commands interactively when run, +you must cause it, when started running for such interactive use in the most +ordinary way, to print or display an announcement including an appropriate +copyright notice and a notice that there is no warranty (or else, saying that +you provide a warranty) and that users may redistribute the program under +these conditions, and telling the user how to view a copy of this License. +(Exception: if the Program itself is interactive but does not normally print +such an announcement, your work based on the Program is not required to print +an announcement.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Program, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Program. + +In addition, mere aggregation of another work not based on the Program with +the Program (or with a work based on the Program) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may copy and distribute the Program (or a work based on it, under Section +2) in object code or executable form under the terms of Sections 1 and 2 above +provided that you also do one of the following: + +a) Accompany it with the complete corresponding machine-readable source code, +which must be distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, + +b) Accompany it with a written offer, valid for at least three years, to give +any third party, for a charge no more than your cost of physically performing +source distribution, a complete machine-readable copy of the corresponding +source code, to be distributed under the terms of Sections 1 and 2 above on +a medium customarily used for software interchange; or, + +c) Accompany it with the information you received as to the offer to distribute +corresponding source code. (This alternative is allowed only for noncommercial +distribution and only if you received the program in object code or executable +form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all +the source code for all modules it contains, plus any associated interface +definition files, plus the scripts used to control compilation and installation +of the executable. However, as a special exception, the source code distributed +need not include anything that is normally distributed (in either source or +binary form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component itself +accompanies the executable. + +If distribution of executable or object code is made by offering access to +copy from a designated place, then offering equivalent access to copy the +source code from the same place counts as distribution of the source code, +even though third parties are not compelled to copy the source along with +the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except +as expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate +your rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses terminated +so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Program or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Program +(or any work based on the Program), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), +the recipient automatically receives a license from the original licensor +to copy, distribute or modify the Program subject to these terms and conditions. +You may not impose any further restrictions on the recipients' exercise of +the rights granted herein. You are not responsible for enforcing compliance +by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of +this License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Program at all. For example, if a +patent license would not permit royalty-free redistribution of the Program +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and +the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system, which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Program under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of +the General Public License from time to time. Such new versions will be similar +in spirit to the present version, but may differ in detail to address new +problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Program does not specify a version number of this License, you may choose +any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software Foundation, +write to the Free Software Foundation; we sometimes make exceptions for this. +Our decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing and reuse +of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA +OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible +use to the public, the best way to achieve this is to make it free software +which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach +them to the start of each source file to most effectively convey the exclusion +of warranty; and each file should have at least the "copyright" line and a +pointer to where the full notice is found. + +one line to give the program's name and an idea of what it does. Copyright +(C) yyyy name of author + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 51 Franklin +Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how +to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when +it starts in an interactive mode: + +Gnomovision version 69, Copyright (C) year name of author Gnomovision comes +with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, +and you are welcome to redistribute it under certain conditions; type `show +c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may be +called something other than `show w' and `show c'; they could even be mouse-clicks +or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the program, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' +(which makes passes at compilers) written by James Hacker. + +signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice diff --git a/local/recipes/libs/polkit-qt6/source/LICENSES/LGPL-2.0-or-later.txt b/local/recipes/libs/polkit-qt6/source/LICENSES/LGPL-2.0-or-later.txt new file mode 100644 index 0000000000..ec9eedc542 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/LICENSES/LGPL-2.0-or-later.txt @@ -0,0 +1,444 @@ +GNU LIBRARY GENERAL PUBLIC LICENSE + +Version 2, June 1991 + +Copyright (C) 1991 Free Software Foundation, Inc. +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is numbered 2 +because it goes with version 2 of the ordinary GPL.] + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public Licenses are intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. + +This license, the Library General Public License, applies to some specially +designated Free Software Foundation software, and to any other libraries whose +authors decide to use it. You can use it for your libraries, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you +wish), that you receive source code or can get it if you want it, that you +can change the software or use pieces of it in new free programs; and that +you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the library, or if you modify it. + +For example, if you distribute copies of the library, whether gratis or for +a fee, you must give the recipients all the rights that we gave you. You must +make sure that they, too, receive or can get the source code. If you link +a program with the library, you must provide complete object files to the +recipients so that they can relink them with the library, after making changes +to the library and recompiling it. And you must show them these terms so they +know their rights. + +Our method of protecting your rights has two steps: (1) copyright the library, +and (2) offer you this license which gives you legal permission to copy, distribute +and/or modify the library. + +Also, for each distributor's protection, we want to make certain that everyone +understands that there is no warranty for this free library. If the library +is modified by someone else and passed on, we want its recipients to know +that what they have is not the original version, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that companies distributing free software will individually +obtain patent licenses, thus in effect transforming the program into proprietary +software. To prevent this, we have made it clear that any patent must be licensed +for everyone's free use or not licensed at all. + +Most GNU software, including some libraries, is covered by the ordinary GNU +General Public License, which was designed for utility programs. This license, +the GNU Library General Public License, applies to certain designated libraries. +This license is quite different from the ordinary one; be sure to read it +in full, and don't assume that anything in it is the same as in the ordinary +license. + +The reason we have a separate public license for some libraries is that they +blur the distinction we usually make between modifying or adding to a program +and simply using it. Linking a program with a library, without changing the +library, is in some sense simply using the library, and is analogous to running +a utility program or application program. However, in a textual and legal +sense, the linked executable is a combined work, a derivative of the original +library, and the ordinary General Public License treats it as such. + +Because of this blurred distinction, using the ordinary General Public License +for libraries did not effectively promote software sharing, because most developers +did not use the libraries. We concluded that weaker conditions might promote +sharing better. + +However, unrestricted linking of non-free programs would deprive the users +of those programs of all benefit from the free status of the libraries themselves. +This Library General Public License is intended to permit developers of non-free +programs to use free libraries, while preserving your freedom as a user of +such programs to change the free libraries that are incorporated in them. +(We have not seen how to achieve this as regards changes in header files, +but we have achieved it as regards changes in the actual functions of the +Library.) The hope is that this will lead to faster development of free libraries. + +The precise terms and conditions for copying, distribution and modification +follow. Pay close attention to the difference between a "work based on the +library" and a "work that uses the library". The former contains code derived +from the library, while the latter only works together with the library. + +Note that it is possible for a library to be covered by the ordinary General +Public License rather than by this special one. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library which contains a +notice placed by the copyright holder or other authorized party saying it +may be distributed under the terms of this Library General Public License +(also called "this License"). Each licensee is addressed as "you". + +A "library" means a collection of software functions and/or data prepared +so as to be conveniently linked with application programs (which use some +of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work which has +been distributed under these terms. A "work based on the Library" means either +the Library or any derivative work under copyright law: that is to say, a +work containing the Library or a portion of it, either verbatim or with modifications +and/or translated straightforwardly into another language. (Hereinafter, translation +is included without limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for making modifications +to it. For a library, complete source code means all the source code for all +modules it contains, plus any associated interface definition files, plus +the scripts used to control compilation and installation of the library. + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running a program +using the Library is not restricted, and output from such a program is covered +only if its contents constitute a work based on the Library (independent of +the use of the Library in a tool for writing it). Whether that is true depends +on what the Library does and what the program that uses the Library does. + +1. You may copy and distribute verbatim copies of the Library's complete source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and disclaimer +of warranty; keep intact all the notices that refer to this License and to +the absence of any warranty; and distribute a copy of this License along with +the Library. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Library or any portion of it, +thus forming a work based on the Library, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + + a) The modified work must itself be a software library. + +b) You must cause the files modified to carry prominent notices stating that +you changed the files and the date of any change. + +c) You must cause the whole of the work to be licensed at no charge to all +third parties under the terms of this License. + +d) If a facility in the modified Library refers to a function or a table of +data to be supplied by an application program that uses the facility, other +than as an argument passed when the facility is invoked, then you must make +a good faith effort to ensure that, in the event an application does not supply +such function or table, the facility still operates, and performs whatever +part of its purpose remains meaningful. + +(For example, a function in a library to compute square roots has a purpose +that is entirely well-defined independent of the application. Therefore, Subsection +2d requires that any application-supplied function or table used by this function +must be optional: if the application does not supply it, the square root function +must still compute square roots.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Library, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Library. + +In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may opt to apply the terms of the ordinary GNU General Public License +instead of this License to a given copy of the Library. To do this, you must +alter all the notices that refer to this License, so that they refer to the +ordinary GNU General Public License, version 2, instead of to this License. +(If a newer version than version 2 of the ordinary GNU General Public License +has appeared, then you can specify that version instead if you wish.) Do not +make any other change in these notices. + +Once this change is made in a given copy, it is irreversible for that copy, +so the ordinary GNU General Public License applies to all subsequent copies +and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of the Library +into a program that is not a library. + +4. You may copy and distribute the Library (or a portion or derivative of +it, under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you accompany it with the complete corresponding +machine-readable source code, which must be distributed under the terms of +Sections 1 and 2 above on a medium customarily used for software interchange. + +If distribution of object code is made by offering access to copy from a designated +place, then offering equivalent access to copy the source code from the same +place satisfies the requirement to distribute the source code, even though +third parties are not compelled to copy the source along with the object code. + +5. A program that contains no derivative of any portion of the Library, but +is designed to work with the Library by being compiled or linked with it, +is called a "work that uses the Library". Such a work, in isolation, is not +a derivative work of the Library, and therefore falls outside the scope of +this License. + +However, linking a "work that uses the Library" with the Library creates an +executable that is a derivative of the Library (because it contains portions +of the Library), rather than a "work that uses the library". The executable +is therefore covered by this License. Section 6 states terms for distribution +of such executables. + +When a "work that uses the Library" uses material from a header file that +is part of the Library, the object code for the work may be a derivative work +of the Library even though the source code is not. Whether this is true is +especially significant if the work can be linked without the Library, or if +the work is itself a library. The threshold for this to be true is not precisely +defined by law. + +If such an object file uses only numerical parameters, data structure layouts +and accessors, and small macros and small inline functions (ten lines or less +in length), then the use of the object file is unrestricted, regardless of +whether it is legally a derivative work. (Executables containing this object +code plus portions of the Library will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may distribute +the object code for the work under the terms of Section 6. Any executables +containing that work also fall under Section 6, whether or not they are linked +directly with the Library itself. + +6. As an exception to the Sections above, you may also compile or link a "work +that uses the Library" with the Library to produce a work containing portions +of the Library, and distribute that work under terms of your choice, provided +that the terms permit modification of the work for the customer's own use +and reverse engineering for debugging such modifications. + +You must give prominent notice with each copy of the work that the Library +is used in it and that the Library and its use are covered by this License. +You must supply a copy of this License. If the work during execution displays +copyright notices, you must include the copyright notice for the Library among +them, as well as a reference directing the user to the copy of this License. +Also, you must do one of these things: + +a) Accompany the work with the complete corresponding machine-readable source +code for the Library including whatever changes were used in the work (which +must be distributed under Sections 1 and 2 above); and, if the work is an +executable linked with the Library, with the complete machine-readable "work +that uses the Library", as object code and/or source code, so that the user +can modify the Library and then relink to produce a modified executable containing +the modified Library. (It is understood that the user who changes the contents +of definitions files in the Library will not necessarily be able to recompile +the application to use the modified definitions.) + +b) Accompany the work with a written offer, valid for at least three years, +to give the same user the materials specified in Subsection 6a, above, for +a charge no more than the cost of performing this distribution. + +c) If distribution of the work is made by offering access to copy from a designated +place, offer equivalent access to copy the above specified materials from +the same place. + +d) Verify that the user has already received a copy of these materials or +that you have already sent this user a copy. + +For an executable, the required form of the "work that uses the Library" must +include any data and utility programs needed for reproducing the executable +from it. However, as a special exception, the source code distributed need +not include anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the operating +system on which the executable runs, unless that component itself accompanies +the executable. + +It may happen that this requirement contradicts the license restrictions of +other proprietary libraries that do not normally accompany the operating system. +Such a contradiction means you cannot use both them and the Library together +in an executable that you distribute. + +7. You may place library facilities that are a work based on the Library side-by-side +in a single library together with other library facilities not covered by +this License, and distribute such a combined library, provided that the separate +distribution of the work based on the Library and of the other library facilities +is otherwise permitted, and provided that you do these two things: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities. This must be distributed +under the terms of the Sections above. + +b) Give prominent notice with the combined library of the fact that part of +it is a work based on the Library, and explaining where to find the accompanying +uncombined form of the same work. + +8. You may not copy, modify, sublicense, link with, or distribute the Library +except as expressly provided under this License. Any attempt otherwise to +copy, modify, sublicense, link with, or distribute the Library is void, and +will automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +9. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Library or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Library +(or any work based on the Library), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +10. Each time you redistribute the Library (or any work based on the Library), +the recipient automatically receives a license from the original licensor +to copy, distribute, link with or modify the Library subject to these terms +and conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties to this License. + +11. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of +this License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Library at all. For example, if a +patent license would not permit royalty-free redistribution of the Library +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +12. If the distribution and/or use of the Library is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Library under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +13. The Free Software Foundation may publish revised and/or new versions of +the Library General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Library specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Library does not specify a license version number, you may choose any version +ever published by the Free Software Foundation. + +14. If you wish to incorporate parts of the Library into other free programs +whose distribution conditions are incompatible with these, write to the author +to ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make exceptions +for this. Our decision will be guided by the two goals of preserving the free +status of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + +NO WARRANTY + +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA +OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest possible +use to the public, we recommend making it free software that everyone can +redistribute and change. You can do so by permitting redistribution under +these terms (or, alternatively, under the terms of the ordinary General Public +License). + +To apply these terms, attach the following notices to the library. It is safest +to attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the "copyright" +line and a pointer to where the full notice is found. + + one line to give the library's name and an idea of what it does. + Copyright (C) year name of author + +This library is free software; you can redistribute it and/or modify it under +the terms of the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for +more details. + +You should have received a copy of the GNU Library General Public License +along with this library; if not, write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the library, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in +the library `Frob' (a library for tweaking knobs) written +by James Random Hacker. + +signature of Ty Coon, 1 April 1990 +Ty Coon, President of Vice + +That's all there is to it! diff --git a/local/recipes/libs/polkit-qt6/source/Mainpage.dox b/local/recipes/libs/polkit-qt6/source/Mainpage.dox new file mode 100644 index 0000000000..ccdf50a151 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/Mainpage.dox @@ -0,0 +1,107 @@ +/** +\mainpage Polkit-qt-1 - Qt wrapper around polkit-1 + +\section polkitqt1_overview Overview + +\note Please note that if you're developing an application which can rely not just on Qt modules, + but also Qt extensions like from the KDE Frameworks, you might want to use instead + KAuth from KDE Frameworks. + +polkit-qt-1 aims to make it easy for Qt developers to take advantage of +polkit API. It is a convenience wrapper around QAction and QAbstractButton +that lets you integrate those two components easily with polkit. + +polkit-qt-1 is not a direct replacement of polkit-qt: it is based on polkit-1, which is not +backwards compatible in any way with Policykit <= 0.9, which was the backend of polkit-qt. +You are encouraged to port polkit-qt applications to polkit-qt or KAuth (from KDE Frameworks), +since PolicyKit <= 0.9 is no longer maintained. + +polkit-qt-1 is split in three libraries: polkit-qt-core-1, polkit-qt-gui-1 and polkit-qt-agent-1 + +\b polkit-qt-core-1 lets you control actions and authentication without a GUI, with some very +simple functions. It also lets you retrieve and control useful information on the polkit +authority. You will be mostly interested in the \c Authority class. + +\b polkit-qt-gui-1 lets you easily associate GUI items with polkit actions. Through some simple +wrapper classes you are able to associate QAction and QAbstractButton to a polkit action, +and get their properties changed accordingly to polkit's result. It includes the classes +Action, ActionButton and ActionButtons + +\b polkit-qt-agent-1 lets you write your own polkit authentication agents in a very simple way. + +\li A sample usage of polkit-qt-1 can be found in \ref polkitqt1_example +\li Alphabetical Class List +\li Class Hierarchy + + + + +\page polkitqt1_example Polkit-qt-1 usage example + +You can find an example usage of Polkit-qt-1 in the examples/ dir. You can +build it by passing \c -DBUILD_EXAMPLES=TRUE to your cmake line. The structure +consists of a .ui file and a main class, to demonstrate how easy it is to integrate +polkit support in an existing application. Let's see some details about it: + +\code +bt = new ActionButton(kickPB, "org.qt.policykit.examples.kick", this); +bt->setText("Kick... (long)"); +// here we set the behavior of PolKitResul = No +bt->setVisible(true, Action::No); +bt->setEnabled(true, Action::No); +bt->setText("Kick (long)", Action::No); +bt->setIcon(QPixmap(":/Icons/custom-no.png"), Action::No); +bt->setToolTip("If your admin wasn't annoying, you could do this", Action::No); +// here we set the behavior of PolKitResul = Auth +bt->setVisible(true, Action::Auth); +bt->setEnabled(true, Action::Auth); +bt->setText("Kick... (long)", Action::Auth); +bt->setIcon(QPixmap(":/Icons/action-locked-default.png"), Action::Auth); +bt->setToolTip("Only card carrying tweakers can do this!", Action::Auth); +// here we set the behavior of PolKitResul = Yes +bt->setVisible(true, Action::Yes); +bt->setEnabled(true, Action::Yes); +bt->setText("Kick! (long)", Action::Yes); +bt->setIcon(QPixmap(":/Icons/custom-yes.png"), Action::Yes); +bt->setToolTip("Go ahead, kick kick kick!", Action::Yes); +\endcode + +This small paragraph sets up an action button using an existing button defined in the +UI file, \c kickPB . As you can see, you can set custom properties on your button depending +on the action status/result. The code is mostly self-explainatory + +\code +bt = new ActionButtons(QList() << listenPB << listenCB, + "org.qt.policykit.examples.listen", this); +bt->setIcon(QPixmap(":/Icons/action-locked.png")); +bt->setIcon(QPixmap(":/Icons/action-unlocked.png"), Action::Yes); +bt->setText("Click to make changes..."); +\endcode + +This demonstrates the use of ActionButtons, that lets you associate multiple buttons with a +single action with extreme ease. \c listenPB and \c listenCB, both defined in the ui file, +are kept in sync with the action. + +\code +connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); +connect(bt, SIGNAL(clicked(QAbstractButton*,bool)), bt, SLOT(activate())); +connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); +\endcode + +Those three signals are all you need to control the action and the activation. Action::triggered() +lets you start the activation/revoke when needed, ActionButton::clicked() lets you do the same thing +with even more ease, just by manually connecting the signal to ActionButton::activate() (see the docs +to understand why this connection doesn't happen automatically), and Action::authorized() signal notifies +you when polkit has authorized you to perform the action. + +As you can see, usage of polkit-qt-1 is extremely simple. Have a look at the complete example +and to the API Docs for more details. + + +*/ + +// DOXYGEN_PROJECTVERSION=0.96.1 +// DOXYGEN_PROJECTNAME=PolkitQt-1 +// DOXYGEN_ENABLE=YES + +// vim:ts=4:sw=4:expandtab:filetype=doxygen diff --git a/local/recipes/libs/polkit-qt6/source/PolkitQt-1Config.cmake.in b/local/recipes/libs/polkit-qt6/source/PolkitQt-1Config.cmake.in new file mode 100644 index 0000000000..e09678c0f3 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/PolkitQt-1Config.cmake.in @@ -0,0 +1,55 @@ +@PACKAGE_INIT@ + +# Config file for POLKITQT-1 +# The following variables are defined: +# POLKITQT-1_FOUND - True if POLKITQT-1 has been found. +# POLKITQT-1_INCLUDE_DIR - The include directory. +# POLKITQT-1_LIB_DIR - The libraries directory. +# POLKITQT-1_LIBRARIES - Libraries needed to use PolkitQt-1. + +########## The PolkitQt-1 version ########## +set(POLKITQT-1_VERSION_MAJOR @POLKITQT-1_VERSION_MAJOR@) +set(POLKITQT-1_VERSION_MINOR @POLKITQT-1_VERSION_MINOR@) +set(POLKITQT-1_VERSION_PATCH @POLKITQT-1_VERSION_PATCH@) +set(POLKITQT-1_VERSION @POLKITQT-1_VERSION_STRING@) +set(POLKITQT-1_VERSION_STRING "@POLKITQT-1_VERSION_STRING@") +######################################### + +########## Install dirs ########## +if(NOT POLKITQT-1_INSTALL_DIR) + set(POLKITQT-1_INSTALL_DIR "@CMAKE_INSTALL_PREFIX@") +endif(NOT POLKITQT-1_INSTALL_DIR) + +set_and_check(POLKITQT-1_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@/@POLKITQT-1_INCLUDE_PATH@") +set_and_check(POLKITQT-1_INCLUDE_DIRS "${POLKITQT-1_INCLUDE_DIR}") +set_and_check(POLKITQT-1_LIB_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@") +set(POLKITQT-1_POLICY_FILES_INSTALL_DIR "${POLKITQT-1_INSTALL_DIR}/share/polkit-1/actions") +################################## + +########## Compatibility ########## +if(WIN32) +if(MINGW) + set(POLKITQT-1_CORE_LIBRARY "${POLKITQT-1_LIB_DIR}/lib@POLKITQT-1_CORE_PCNAME@.dll.a") + set(POLKITQT-1_AGENT_LIBRARY "${POLKITQT-1_LIB_DIR}/lib@POLKITQT-1_AGENT_PCNAME@.dll.a") + set(POLKITQT-1_GUI_LIBRARY "${POLKITQT-1_LIB_DIR}/lib@POLKITQT-1_GUI_PCNAME@.dll.a") +else(MINGW) + set(POLKITQT-1_CORE_LIBRARY "${POLKITQT-1_LIB_DIR}/@POLKITQT-1_CORE_PCNAME@.lib") + set(POLKITQT-1_AGENT_LIBRARY "${POLKITQT-1_LIB_DIR}/@POLKITQT-1_AGENT_PCNAME@.lib") + set(POLKITQT-1_GUI_LIBRARY "${POLKITQT-1_LIB_DIR}/@POLKITQT-1_GUI_PCNAME@.lib") +endif(MINGW) +elseif(APPLE) + set(POLKITQT-1_CORE_LIBRARY "${POLKITQT-1_LIB_DIR}/lib@POLKITQT-1_CORE_PCNAME@.dylib") + set(POLKITQT-1_AGENT_LIBRARY "${POLKITQT-1_LIB_DIR}/lib@POLKITQT-1_AGENT_PCNAME@.dylib") + set(POLKITQT-1_GUI_LIBRARY "${POLKITQT-1_LIB_DIR}/lib@POLKITQT-1_GUI_PCNAME@.dylib") +else() + set(POLKITQT-1_CORE_LIBRARY "${POLKITQT-1_LIB_DIR}/lib@POLKITQT-1_CORE_PCNAME@.so") + set(POLKITQT-1_AGENT_LIBRARY "${POLKITQT-1_LIB_DIR}/lib@POLKITQT-1_AGENT_PCNAME@.so") + set(POLKITQT-1_GUI_LIBRARY "${POLKITQT-1_LIB_DIR}/lib@POLKITQT-1_GUI_PCNAME@.so") +endif() + +########## The PolkitQt-1 libraries ########## +# Load the exported targets. +include("${CMAKE_CURRENT_LIST_DIR}/@POLKITQT-1_CAMEL_NAME@Targets.cmake") +set(POLKITQT-1_LIBRARIES @POLKITQT-1_CAMEL_NAME@::Core @POLKITQT-1_CAMEL_NAME@::Gui @POLKITQT-1_CAMEL_NAME@::Agent) +########################################### + diff --git a/local/recipes/libs/polkit-qt6/source/README b/local/recipes/libs/polkit-qt6/source/README new file mode 100644 index 0000000000..efc31d8674 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/README @@ -0,0 +1,23 @@ +Polkit-qt +======== + +What is Polkit-qt? +------------------ +Polkit-qt is a library that lets developers use the PolicyKit API through a nice +Qt-styled API. It is mainly a wrapper around QAction and QAbstractButton that +lets you integrate those two component easily with PolicyKit + +This directory contains the sources of the library. + +Structure +---------- + + * cmake/ + Contains the cmake checks that are needed to build the library, + and a FindPolkitQt.cmake module. + + * . + Contains the sources of the library + + +See INSTALL for installation instructions. diff --git a/local/recipes/libs/polkit-qt6/source/README.porting b/local/recipes/libs/polkit-qt6/source/README.porting new file mode 100644 index 0000000000..d2074ea979 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/README.porting @@ -0,0 +1,25 @@ +Policy Kit 1 support for polkit-qt +================================== + +This is initial port to PK1. + +What's working? +--------------- +polkit-qt-core +polkit-qt-gui + +TO-DO +----- +* polkit-qt-core + - temporary authorization handling functions + - move from Auth namespace to Authority class? + - tests + +Documentation +------------- +http://fedoraproject.org/wiki/Features/PolicyKitOne +http://hal.freedesktop.org/docs/polkit/index.html + +Porting guide +------------- +http://cgit.freedesktop.org/PolicyKit/tree/docs/PORTING-GUIDE diff --git a/local/recipes/libs/polkit-qt6/source/TODO b/local/recipes/libs/polkit-qt6/source/TODO new file mode 100644 index 0000000000..596936ff0c --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/TODO @@ -0,0 +1,11 @@ +TODO +==== + +- Policy Kit 1 port + * polkit-qt + + Console Kit support + + * polkit-qt-gui + + authorization checking for non privileged user + +- document Listener and co. diff --git a/local/recipes/libs/polkit-qt6/source/agent/CMakeLists.txt b/local/recipes/libs/polkit-qt6/source/agent/CMakeLists.txt new file mode 100644 index 0000000000..ba95bfe24c --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/agent/CMakeLists.txt @@ -0,0 +1,39 @@ +add_library(${POLKITQT-1_AGENT_PCNAME} SHARED) +add_library(${POLKITQT-1_CAMEL_NAME}::Agent ALIAS ${POLKITQT-1_AGENT_PCNAME}) + +target_sources(${POLKITQT-1_AGENT_PCNAME} PRIVATE + polkitqt1-agent-session.cpp + polkitqt1-agent-listener.cpp + listeneradapter.cpp + polkitqtlistener.cpp +) +generate_export_header(${POLKITQT-1_AGENT_PCNAME} + BASE_NAME polkitqt1-agent + EXPORT_FILE_NAME polkitqt1-agent-export.h +) + +target_link_libraries(${POLKITQT-1_AGENT_PCNAME} + PUBLIC + Qt${QT_MAJOR_VERSION}::Core + ${POLKITQT-1_CORE_PCNAME} + PRIVATE + Qt${QT_MAJOR_VERSION}::Core + PkgConfig::POLKIT_AGENT + PkgConfig::GOBJECT +) + +set_target_properties(${POLKITQT-1_AGENT_PCNAME} PROPERTIES VERSION ${POLKITQT-1_LIBRARY_VERSION} + SOVERSION ${POLKITQT-1_ABI_VERSION} + DEFINE_SYMBOL MAKE_POLKITQT1_LIB + EXPORT_NAME Agent) + +target_include_directories(${POLKITQT-1_AGENT_PCNAME} + INTERFACE + $ + $ + $ +) + +install(TARGETS ${POLKITQT-1_AGENT_PCNAME} EXPORT ${POLKITQT-1_CAMEL_NAME}Export ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION bin) diff --git a/local/recipes/libs/polkit-qt6/source/agent/listeneradapter.cpp b/local/recipes/libs/polkit-qt6/source/agent/listeneradapter.cpp new file mode 100644 index 0000000000..a1b84e94a6 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/agent/listeneradapter.cpp @@ -0,0 +1,135 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "listeneradapter_p.h" +#include +#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE 1 +#include + +namespace PolkitQt1 +{ + +namespace Agent +{ + +class ListenerAdapterHelper +{ +public: + ListenerAdapterHelper() : q(nullptr) {} + ~ListenerAdapterHelper() { + delete q; + } + ListenerAdapter *q; +}; + +Q_GLOBAL_STATIC(ListenerAdapterHelper, s_globalListenerAdapter) + +ListenerAdapter *ListenerAdapter::instance() +{ + if (!s_globalListenerAdapter()->q) { + new ListenerAdapter(); + } + + return s_globalListenerAdapter()->q; +} + +ListenerAdapter::ListenerAdapter(QObject *parent) + : QObject(parent) +{ + Q_ASSERT(!s_globalListenerAdapter()->q); + s_globalListenerAdapter()->q = this; +} + +Listener* ListenerAdapter::findListener(PolkitAgentListener *listener) +{ + Listener *listItem; + + Q_FOREACH(listItem, m_listeners) { + Q_ASSERT(listItem); + + if (listItem->listener() == listener) { + return listItem; + } + } + + return nullptr; +} + +void ListenerAdapter::polkit_qt_listener_initiate_authentication(PolkitAgentListener *listener, + const gchar *action_id, + const gchar *message, + const gchar *icon_name, + PolkitDetails *details, + const gchar *cookie, + GList *identities, + GCancellable *cancellable, + GSimpleAsyncResult *result) +{ + qDebug() << "polkit_qt_listener_initiate_authentication callback for " << listener; + + PolkitQt1::Details dets(details); + + Listener *list = findListener(listener); + + // Polkit enumerates identities without regard for their hash value, potentially leading to duplicated entries. + // Unique the identities on our end. + // https://github.com/polkit-org/polkit/issues/542 + QHash uniqueIdentities; + for (GList *entry = g_list_first(identities); entry != nullptr; entry = g_list_next(entry)) { + auto identity = static_cast(entry->data); + uniqueIdentities.insert(polkit_identity_hash(identity), PolkitQt1::Identity(identity)); + } + + list->initiateAuthentication(QString::fromUtf8(action_id), + QString::fromUtf8(message), + QString::fromUtf8(icon_name), + dets, + QString::fromUtf8(cookie), + uniqueIdentities.values(), + new AsyncResult(result)); +} + +gboolean ListenerAdapter::polkit_qt_listener_initiate_authentication_finish(PolkitAgentListener *listener, + GAsyncResult *res, + GError **error) +{ + qDebug() << "polkit_qt_listener_initiate_authentication_finish callback for " << listener; + + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT(res); + if (g_simple_async_result_propagate_error(simple, error)) { + return false; + } + return true; +} + +void ListenerAdapter::cancelled_cb(PolkitAgentListener *listener) +{ + qDebug() << "cancelled_cb for " << listener; + + Listener *list = findListener(listener); + + list->cancelAuthentication(); +} + +void ListenerAdapter::addListener(Listener *listener) +{ + qDebug() << "Adding new listener " << listener << "for " << listener->listener(); + + m_listeners.append(listener); +} + +void ListenerAdapter::removeListener(Listener *listener) +{ + qDebug() << "Removing listener " << listener; + + // should be safe as we don't have more than one same listener registered in one time + m_listeners.removeOne(listener); +} + +} + +} diff --git a/local/recipes/libs/polkit-qt6/source/agent/listeneradapter_p.h b/local/recipes/libs/polkit-qt6/source/agent/listeneradapter_p.h new file mode 100644 index 0000000000..deb371121d --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/agent/listeneradapter_p.h @@ -0,0 +1,70 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef LISTENER_ADAPTER_P_H +#define LISTENER_ADAPTER_P_H + +#include + +#include "polkitqt1-agent-listener.h" +#include "polkitqt1-identity.h" +#include "polkitqt1-details.h" + +typedef struct _GList GList; +typedef struct _GCancellable GCancellable; +typedef struct _GAsyncResult GAsyncResult; +typedef struct _GSimpleAsyncResult GSimpleAsyncResult; +typedef struct _GError GError; +typedef int gboolean; +typedef char gchar; + +namespace PolkitQt1 +{ + +namespace Agent +{ + +class AsyncResult; +class Listener; +class ListenerAdapter : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(ListenerAdapter) +public: + static ListenerAdapter* instance(); + ~ListenerAdapter() override {} + + void polkit_qt_listener_initiate_authentication(PolkitAgentListener *listener, + const gchar *action_id, + const gchar *message, + const gchar *icon_name, + PolkitDetails *details, + const gchar *cookie, + GList *identities, + GCancellable *cancellable, + GSimpleAsyncResult *result); + + gboolean polkit_qt_listener_initiate_authentication_finish(PolkitAgentListener *listener, + GAsyncResult *res, + GError **error); + void cancelled_cb(PolkitAgentListener *listener); +private: + void addListener(Listener *listener); + void removeListener(Listener *listener); + Listener* findListener(PolkitAgentListener *listener); + + explicit ListenerAdapter(QObject *parent = nullptr); + QList m_listeners; + + friend class Listener; +}; + +} + +} + +#endif diff --git a/local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-listener.cpp b/local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-listener.cpp new file mode 100644 index 0000000000..27348b13f3 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-listener.cpp @@ -0,0 +1,109 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "polkitqt1-agent-listener.h" + +#include + +#include "polkitqtlistener_p.h" + +#include "polkitqt1-authority.h" +#include "polkitqt1-subject.h" +#include "polkitqt1-identity.h" +#include "polkitqt1-details.h" + +namespace PolkitQt1 +{ + +namespace Agent +{ + +class ListenerPrivate +{ +public: + PolkitAgentListener *listener; +#ifndef POLKIT_QT_1_COMPATIBILITY_MODE + void *registeredHandle; +#endif +}; + +Listener::Listener(QObject *parent) + : QObject(parent), d(new ListenerPrivate) +{ + d->listener = polkit_qt_listener_new(); + + qDebug() << "New PolkitAgentListener " << d->listener; + + ListenerAdapter::instance()->addListener(this); +} + +Listener::Listener(PolkitAgentListener *listener, QObject *parent) + : QObject(parent), d(new ListenerPrivate) +{ + d->listener = listener; + + if (d->listener != nullptr) { + g_object_ref(d->listener); + } +} + +Listener::~Listener() +{ + qDebug("Destroying listener"); + + ListenerAdapter::instance()->removeListener(this); +#ifndef POLKIT_QT_1_COMPATIBILITY_MODE + if (d->registeredHandle) { + polkit_agent_listener_unregister(d->registeredHandle); + } +#endif + if (d->listener != nullptr) { + g_object_unref(d->listener); + } +} + +bool Listener::registerListener(const PolkitQt1::Subject &subject, const QString &objectPath) +{ + GError *error = nullptr; + +#ifndef POLKIT_QT_1_COMPATIBILITY_MODE + d->registeredHandle = polkit_agent_listener_register(d->listener, + POLKIT_AGENT_REGISTER_FLAGS_NONE, +#else + bool r = polkit_agent_register_listener(d->listener, +#endif + subject.subject(), + objectPath.toLatin1().data(), +#ifndef POLKIT_QT_1_COMPATIBILITY_MODE + nullptr, +#endif + &error); + + if (error != nullptr) { + qWarning() << QString("Cannot register authentication agent: %1").arg(error->message); + g_error_free(error); + return false; + } +#ifndef POLKIT_QT_1_COMPATIBILITY_MODE + if (d->registeredHandle == nullptr) { + qWarning() << QString("Cannot register authentication agent!"); + return false; + } + return true; +#else + return r; +#endif +} + +const PolkitAgentListener *Listener::listener() +{ + return d->listener; +} + +} + +} diff --git a/local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-listener.h b/local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-listener.h new file mode 100644 index 0000000000..a40ff41103 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-listener.h @@ -0,0 +1,147 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef POLKITQT1_AGENT_LISTENER_H +#define POLKITQT1_AGENT_LISTENER_H + +#include +#include + +#include "polkitqt1-agent-session.h" + +#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE 1 + +typedef struct _PolkitAgentListener PolkitAgentListener; + +namespace PolkitQt1 +{ +class Subject; +class Identity; +class Details; +} + +namespace PolkitQt1 +{ + +namespace Agent +{ + +class ListenerPrivate; +/** + * \class Listener polkitqt1-agent-listener.h Listener + * \author Jaroslav Reznik + * + * \brief Listener is abstract class used for implementing authentication agents. + * + * To implement an authentication agent, just subclass this class and implement + * virtual functions initiateAuthentication, initiateAuthenticationFinish + * and cancelAuthentication. + * + * You can also use Session class to authenticate users however it isn't required. + * \sa Session + */ +class POLKITQT1_AGENT_EXPORT Listener : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(Listener) +public: + /** + * \brief Constructor of Listener class + */ + Listener(QObject *parent = nullptr); + + /** + * \brief Constructor of Listener class from PolkitAgentListener + * + * \warning Use this only if you are completely aware of what are you doing! + * + * \param listener Pointer to the PolkitAgentListener + * \param parent + */ + explicit Listener(PolkitAgentListener *listener, QObject *parent = nullptr); + + ~Listener() override; + + /** + * \brief Registers listener with polkit daemon as an authentication agent for \p subject. + * + * This is implemented by registering a DBus object at \p objectPath on the unique + * name assigned by the system message bus. + * + * Whenever the polkit daemon needs to authenticate a processes that is related to \p subject, + * the methods initiateAuthentication and initiateAuthenticationFinish will be evoked. + * + * \param subject Subject that listener will be registered for + * \param objectPath DBus object path + * \return \c True if the polkitqt1-agent-listener.has been registered, \c False otherwise + */ + bool registerListener(const PolkitQt1::Subject &subject, const QString &objectPath); + + /** + * \brief Returns pointer to the PolkitAgentListener. + * + * \warning Use this only if you are completely aware of what are you doing! + * + * \return PolkitAgentListener + */ + const PolkitAgentListener *listener(); + +public Q_SLOTS: + /** + * \brief Initiate authentication for the action + * + * This method will be called on a registered authentication agent when the user owning + * the session needs to prove he is one of the identities listed in \p identities. + * + * \note You have to reimplement this method in the subclass. + * + * \param actionId The action to authenticate for + * \param message The message to present to the user + * \param iconName The name of the icon which is representing the action + * \param details Details describing the action + * \param cookie The cookie for the authentization request + * \param identities A list of Identity object that the user can choose to authenticate as + * \param result This AsyncResult MUST be completed by using complete() method when the + * authentication is done. You can pass it to the constructor of the Session class + * and then call session->result()->complete() to mark the action as done. + */ + virtual void initiateAuthentication(const QString &actionId, + const QString &message, + const QString &iconName, + const PolkitQt1::Details &details, + const QString &cookie, + const PolkitQt1::Identity::List &identities, + PolkitQt1::Agent::AsyncResult *result) = 0; + + /** + * TODO: Is this method really required ? + * \brief Finishes an authentication request from the polkit daemon. + * + * \note You have to reimplement this method in the subclass. + * + * \see initiateAuthentication + */ + virtual bool initiateAuthenticationFinish() = 0; + + /** + * TODO: Is this method really required ? + * \brief Cancels an authentication request from the polkit daemon. + * + * \note You have to reimplement this method in the subclass. + * + * \see initiateAuthentication + */ + virtual void cancelAuthentication() = 0; + +private: + QScopedPointer d; +}; +} + +} + +#endif diff --git a/local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-session.cpp b/local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-session.cpp new file mode 100644 index 0000000000..e70ace0880 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-session.cpp @@ -0,0 +1,157 @@ +/* + This file is part of the PolKit1-qt project + SPDX-FileCopyrightText: 2009 Radek Novacek + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "polkitqt1-agent-session.h" + +#include + +#include "polkitqt1-identity.h" + +#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE 1 +#include + +using namespace PolkitQt1::Agent; + +class Session::Private +{ +public: + Private() {} + ~Private(); + + static void completed(PolkitAgentSession *s, gboolean gained_authorization, gpointer user_data); + static void request(PolkitAgentSession *s, gchar *request, gboolean echo_on, gpointer user_data); + static void showError(PolkitAgentSession *s, gchar *text, gpointer user_data); + static void showInfo(PolkitAgentSession *s, gchar *text, gpointer user_data); + + AsyncResult *result; + PolkitAgentSession *polkitAgentSession; +}; + +Session::Private::~Private() +{ + // polkitAgentSession is freed in Session d'tor +} + +Session::Session(const PolkitQt1::Identity &identity, const QString &cookie, AsyncResult *result, QObject *parent) + : QObject(parent) + , d(new Private) +{ + d->result = result; + d->polkitAgentSession = polkit_agent_session_new(identity.identity(), cookie.toUtf8().data()); + g_signal_connect(G_OBJECT(d->polkitAgentSession), "completed", G_CALLBACK(Private::completed), this); + g_signal_connect(G_OBJECT(d->polkitAgentSession), "request", G_CALLBACK(Private::request), this); + g_signal_connect(G_OBJECT(d->polkitAgentSession), "show-error", G_CALLBACK(Private::showError), this); + g_signal_connect(G_OBJECT(d->polkitAgentSession), "show-info", G_CALLBACK(Private::showInfo), this); +} + +Session::Session(PolkitAgentSession *pkAgentSession, QObject *parent) + : QObject(parent) + , d(new Private) +{ + d->polkitAgentSession = pkAgentSession; + if (d->polkitAgentSession) { + g_object_ref(d->polkitAgentSession); + } + g_signal_connect(G_OBJECT(d->polkitAgentSession), "completed", G_CALLBACK(Private::completed), this); + g_signal_connect(G_OBJECT(d->polkitAgentSession), "request", G_CALLBACK(Private::request), this); + g_signal_connect(G_OBJECT(d->polkitAgentSession), "show-error", G_CALLBACK(Private::showError), this); + g_signal_connect(G_OBJECT(d->polkitAgentSession), "show-info", G_CALLBACK(Private::showInfo), this); +} + +Session::~Session() +{ + if (d->polkitAgentSession) + g_object_unref(d->polkitAgentSession); + + delete d; +} + +void Session::initiate() +{ + polkit_agent_session_initiate(d->polkitAgentSession); +} + +void Session::setResponse(const QString &response) +{ + polkit_agent_session_response(d->polkitAgentSession, response.toUtf8().data()); +} + +void Session::cancel() +{ + polkit_agent_session_cancel(d->polkitAgentSession); +} + +AsyncResult *Session::result() +{ + return d->result; +} + +void Session::Private::completed(PolkitAgentSession *s, gboolean gained_authorization, gpointer user_data) +{ + qDebug() << "COMPLETED"; + Session *session = (Session *)user_data; + Q_EMIT(session)->completed(gained_authorization); + + //free session here as polkit documentation asks + g_object_unref(session->d->polkitAgentSession); + session->d->polkitAgentSession = nullptr; +} + +void Session::Private::request(PolkitAgentSession *s, gchar *request, gboolean echo_on, gpointer user_data) +{ + qDebug() << "REQUEST"; + Q_EMIT((Session *)user_data)->request(QString::fromUtf8(request), echo_on); +} + +void Session::Private::showError(PolkitAgentSession *s, gchar *text, gpointer user_data) +{ + qDebug() << "showError"; + Q_EMIT((Session *)user_data)->showError(QString::fromUtf8(text)); +} + +void Session::Private::showInfo(PolkitAgentSession *s, gchar *text, gpointer user_data) +{ + qDebug() << "showInfo"; + Q_EMIT((Session *)user_data)->showInfo(QString::fromUtf8(text)); +} + +// + +class AsyncResult::Private +{ +public: + Private(GSimpleAsyncResult *r) : result(r) {}; + + GSimpleAsyncResult *result; +}; + +AsyncResult::AsyncResult(GSimpleAsyncResult *result) + : d(new Private(result)) +{ +} + +AsyncResult::~AsyncResult() +{ + if (d->result) + g_object_unref(d->result); +} + +void AsyncResult::setCompleted() +{ + if (d->result == nullptr) + return; + g_simple_async_result_complete(d->result); + // Assure that completed won't be called twice + g_object_unref(d->result); + d->result = nullptr; +} + +void AsyncResult::setError(const QString &text) +{ + Q_ASSERT(d->result); + g_simple_async_result_set_error(d->result, POLKIT_ERROR, POLKIT_ERROR_FAILED, "%s", text.toUtf8().data()); +} diff --git a/local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-session.h b/local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-session.h new file mode 100644 index 0000000000..42b30e8d7b --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/agent/polkitqt1-agent-session.h @@ -0,0 +1,168 @@ +/* + This file is part of the PolKit1-qt project + SPDX-FileCopyrightText: 2009 Radek Novacek + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef POLKITQT1_AGENT_SESSION_H +#define POLKITQT1_AGENT_SESSION_H + +#include +#include "polkitqt1-identity.h" +#include "polkitqt1-agent-export.h" + +typedef struct _GSimpleAsyncResult GSimpleAsyncResult; +typedef struct _PolkitAgentSession PolkitAgentSession; + +namespace PolkitQt1 +{ + +/** + * \namespace Agent Agent + * + * \brief Namespace wrapping Polkit-Qt Agent classes + * + * This namespace wraps all Polkit-Qt Agent classes. + */ + +namespace Agent +{ + +/** + * \internal + * \brief Encapsulation of GSimpleAsyncResult to QObject class + */ +class POLKITQT1_AGENT_EXPORT AsyncResult +{ +public: + explicit AsyncResult(GSimpleAsyncResult *result); + virtual ~AsyncResult(); + + /** + * \brief Mark the action that is tied to this result as completed. + */ + void setCompleted(); + + /** + * \brief Sets an error for the asynchronous result. + * Method complete() must be called anyway. + * + * \param text text of the error message + */ + void setError(const QString &text); + +private: + class Private; + Private * const d; +}; + +/** + * \class Session polkitqt1-agent-session.h Session + * \author Radek Novacek + * + * This class is interface for interacting with native + * authentication system for obtaining authorizations. + * + */ +class POLKITQT1_AGENT_EXPORT Session : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(Session) +public: + /** + * Create a new authentication session. + * + * \param identity The identity to authenticate + * \param cookie The cookie obtained from the PolicyKit daemon + * \param result Result of the authentication action. Must be finished using complete() method. + * \param parent + */ + Session(const PolkitQt1::Identity& identity, const QString &cookie, AsyncResult *result = nullptr, QObject *parent = nullptr); + + /** + * Create a new authentication session from PolkitAgentSession object + * + * \warning Use this only if you are completely aware of what are you doing! + * + * \param pkAgentSession PolkitAgentSession object + * \param parent + */ + explicit Session(PolkitAgentSession *pkAgentSession, QObject *parent = nullptr); + + /** + * Destroy authentication session. + */ + ~Session() override; + + /** + * Initiate the authentication session. + * + * Use cancel() to cancel the session. + */ + void initiate(); + + /** + * Method for providing response to requests received via request signal. + * + * \param response Response from the user, typically a password + */ + void setResponse(const QString &response); + + /** + * Cancel the authentication session. + * This will emit the completed() signal. + */ + void cancel(); + + /** + * Get AsyncResult that can be used to finish authentication operation + * + * \return AsyncResult object or NULL if it is not set + */ + AsyncResult *result(); + +Q_SIGNALS: + /** + * This signal will be emitted when the authentication + * polkitqt1-agent-session.has been completed or cancelled. + * + * \param gainedAuthorization \c True if authorization was successfully obtained. + */ + void completed(bool gainedAuthorization); + + /** + * This signal will be emitted when user is requested to answer a question. + * + * \param request The request to show the user, e.g. "name: " or "password: ". + * \param echo \c True if the response to the request SHOULD be echoed on the screen, + * \c False if the response MUST NOT be echoed to the screen. + */ + void request(const QString &request, bool echo); + + /** + * This signal will be emitted when there is information + * related to an error condition to be displayed to the user. + * + * \param text An error string to display to the user. + */ + void showError(const QString &text); + + /** + * This signal will be emitted when there is information + * to be displayed to the user. + * + * \param text A string to be displayed to the user. + */ + void showInfo(const QString &text); + +private: + class Private; + Private * const d; +}; + +} + +} + +#endif // SESSION_H diff --git a/local/recipes/libs/polkit-qt6/source/agent/polkitqtlistener.cpp b/local/recipes/libs/polkit-qt6/source/agent/polkitqtlistener.cpp new file mode 100644 index 0000000000..e8713b54fc --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/agent/polkitqtlistener.cpp @@ -0,0 +1,135 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + SPDX-FileContributor: based on code by David Zeuthen + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + + +#include "polkitqtlistener_p.h" +#include + +#include + +#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE 1 + +using namespace PolkitQt1::Agent; + +/** + * \internal + */ +struct _PolkitQtListener { + PolkitAgentListener parent_instance; +}; + +/** + * \internal + */ +struct _PolkitQtListenerClass { + PolkitAgentListenerClass parent_class; +}; + +static void polkit_qt_listener_initiate_authentication(PolkitAgentListener *listener, + const gchar *action_id, + const gchar *message, + const gchar *icon_name, + PolkitDetails *details, + const gchar *cookie, + GList *identities, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +static gboolean polkit_qt_listener_initiate_authentication_finish(PolkitAgentListener *listener, + GAsyncResult *res, + GError **error); + +G_DEFINE_TYPE(PolkitQtListener, polkit_qt_listener, POLKIT_AGENT_TYPE_LISTENER) + +static void polkit_qt_listener_init(PolkitQtListener *listener) +{ +} + +static void polkit_qt_listener_finalize(GObject *object) +{ + PolkitQtListener *listener; + + listener = POLKIT_QT_LISTENER(object); + + if (G_OBJECT_CLASS(polkit_qt_listener_parent_class)->finalize != nullptr) { + G_OBJECT_CLASS(polkit_qt_listener_parent_class)->finalize(object); + } +} + +static void polkit_qt_listener_class_init(PolkitQtListenerClass *klass) +{ + GObjectClass *gobject_class; + PolkitAgentListenerClass *listener_class; + + gobject_class = G_OBJECT_CLASS(klass); + listener_class = POLKIT_AGENT_LISTENER_CLASS(klass); + + gobject_class->finalize = polkit_qt_listener_finalize; + + listener_class->initiate_authentication = polkit_qt_listener_initiate_authentication; + listener_class->initiate_authentication_finish = polkit_qt_listener_initiate_authentication_finish; +} + +PolkitAgentListener *polkit_qt_listener_new(void) +{ + return POLKIT_AGENT_LISTENER(g_object_new(POLKIT_QT_TYPE_LISTENER, nullptr)); +} + +static void cancelled_cb(GCancellable *cancellable, gpointer user_data) +{ + ListenerAdapter::instance()->cancelled_cb((PolkitAgentListener *)user_data); +} + +static void polkit_qt_listener_initiate_authentication(PolkitAgentListener *agent_listener, + const gchar *action_id, + const gchar *message, + const gchar *icon_name, + PolkitDetails *details, + const gchar *cookie, + GList *identities, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + qDebug() << "Listener adapter polkit_qt_listener_initiate_authentication"; + PolkitQtListener *listener = POLKIT_QT_LISTENER(agent_listener); + + if (cancellable != nullptr) { + g_cancellable_connect(cancellable, + G_CALLBACK(cancelled_cb), + agent_listener, + nullptr); + } + + // The result of asynchronous method will be created here and it will be pushed to the listener. + GSimpleAsyncResult *result = g_simple_async_result_new((GObject *) listener, callback, user_data, agent_listener); + qDebug() << "GSimpleAsyncResult:" << result; + + ListenerAdapter::instance()->polkit_qt_listener_initiate_authentication(agent_listener, + action_id, + message, + icon_name, + details, + cookie, + identities, + cancellable, + result); + +} + +static gboolean polkit_qt_listener_initiate_authentication_finish(PolkitAgentListener *listener, + GAsyncResult *res, + GError **error) +{ + qDebug() << "Listener adapter polkit_qt_listener_initiate_authentication_finish"; + return ListenerAdapter::instance()->polkit_qt_listener_initiate_authentication_finish(listener, + res, + error); +} + diff --git a/local/recipes/libs/polkit-qt6/source/agent/polkitqtlistener_p.h b/local/recipes/libs/polkit-qt6/source/agent/polkitqtlistener_p.h new file mode 100644 index 0000000000..a7ae5200b6 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/agent/polkitqtlistener_p.h @@ -0,0 +1,35 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + SPDX-FileContributor: based on code by David Zeuthen + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef POLKITQT_LISTENER_P_H +#define POLKITQT_LISTENER_P_H + +#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE 1 + +#include "listeneradapter_p.h" + +#include + +G_BEGIN_DECLS + +#define POLKIT_QT_TYPE_LISTENER (polkit_qt_listener_get_type()) +#define POLKIT_QT_LISTENER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_QT_TYPE_LISTENER, PolkitQtListener)) +#define POLKIT_QT_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), POLKIT_QT_TYPE_LISTENER, PolkitQtListenerClass)) +#define POLKIT_QT_LISTENER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_QT_TYPE_LISTENER, PolkitQtListenerClass)) +#define POLKIT_QT_IS_LISTENER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_QT_TYPE_LISTENER)) +#define POLKIT_QT_IS_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_QT_TYPE_LISTENER)) + +typedef struct _PolkitQtListener PolkitQtListener; +typedef struct _PolkitQtListenerClass PolkitQtListenerClass; + +GType polkit_qt_listener_get_type(void) G_GNUC_CONST; +PolkitAgentListener *polkit_qt_listener_new(void); + +G_END_DECLS + +#endif /* POLKIT_QT_LISTENER_H */ diff --git a/local/recipes/libs/polkit-qt6/source/core/CMakeLists.txt b/local/recipes/libs/polkit-qt6/source/core/CMakeLists.txt new file mode 100644 index 0000000000..29bccc73fa --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/core/CMakeLists.txt @@ -0,0 +1,43 @@ +add_library(${POLKITQT-1_CORE_PCNAME} SHARED) +add_library(${POLKITQT-1_CAMEL_NAME}::Core ALIAS ${POLKITQT-1_CORE_PCNAME}) + +target_sources(${POLKITQT-1_CORE_PCNAME} PRIVATE + polkitqt1-authority.cpp + polkitqt1-identity.cpp + polkitqt1-subject.cpp + polkitqt1-temporaryauthorization.cpp + polkitqt1-details.cpp + polkitqt1-actiondescription.cpp +) + +generate_export_header(${POLKITQT-1_CORE_PCNAME} + BASE_NAME polkitqt1-core + EXPORT_FILE_NAME polkitqt1-core-export.h +) + +target_link_libraries(${POLKITQT-1_CORE_PCNAME} + PUBLIC + Qt${QT_MAJOR_VERSION}::Core + PRIVATE + Qt${QT_MAJOR_VERSION}::DBus + PkgConfig::POLKIT_GOBJECT + PkgConfig::GLIB2 + PkgConfig::GOBJECT +) + +set_target_properties(${POLKITQT-1_CORE_PCNAME} PROPERTIES VERSION ${POLKITQT-1_LIBRARY_VERSION} + SOVERSION ${POLKITQT-1_ABI_VERSION} + DEFINE_SYMBOL MAKE_POLKITQT1_LIB + EXPORT_NAME Core) + +target_include_directories(${POLKITQT-1_CORE_PCNAME} + INTERFACE + $ + $ + $ +) + +install(TARGETS ${POLKITQT-1_CORE_PCNAME} EXPORT ${POLKITQT-1_CAMEL_NAME}Export ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION bin) + diff --git a/local/recipes/libs/polkit-qt6/source/core/polkitqt1-actiondescription.cpp b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-actiondescription.cpp new file mode 100644 index 0000000000..198e1acdb4 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-actiondescription.cpp @@ -0,0 +1,133 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + SPDX-FileCopyrightText: 2010 Dario Freddi + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "polkitqt1-actiondescription.h" + +#include + +#include + +namespace PolkitQt1 +{ + +class Q_DECL_HIDDEN ActionDescription::Data : public QSharedData +{ +public: + Data() {} + Data(const Data& other) + : QSharedData(other) + , actionId(other.actionId) + , description(other.description) + , message(other.message) + , vendorName(other.vendorName) + , vendorUrl(other.vendorUrl) + , iconName(other.iconName) + , implicitAny(other.implicitAny) + , implicitInactive(other.implicitInactive) + , implicitActive(other.implicitActive) + { + } + virtual ~Data() {} + + QString actionId; + QString description; + QString message; + QString vendorName; + QString vendorUrl; + QString iconName; + + ActionDescription::ImplicitAuthorization implicitAny; + ActionDescription::ImplicitAuthorization implicitInactive; + ActionDescription::ImplicitAuthorization implicitActive; +}; + +ActionDescription::ActionDescription() + : d(new Data) +{ + +} + +ActionDescription::ActionDescription(PolkitActionDescription *polkitActionDescription) + : d(new Data) +{ + d->actionId = QString::fromUtf8(polkit_action_description_get_action_id(polkitActionDescription)); + d->description = QString::fromUtf8(polkit_action_description_get_description(polkitActionDescription)); + d->message = QString::fromUtf8(polkit_action_description_get_message(polkitActionDescription)); + d->vendorName = QString::fromUtf8(polkit_action_description_get_vendor_name(polkitActionDescription)); + d->vendorUrl = QString::fromUtf8(polkit_action_description_get_vendor_url(polkitActionDescription)); + d->iconName = QString::fromUtf8(polkit_action_description_get_icon_name(polkitActionDescription)); + + d->implicitAny = static_cast(polkit_action_description_get_implicit_any( + polkitActionDescription)); + d->implicitInactive = static_cast(polkit_action_description_get_implicit_inactive( + polkitActionDescription)); + d->implicitActive = static_cast(polkit_action_description_get_implicit_active( + polkitActionDescription)); +} + +ActionDescription::ActionDescription(const PolkitQt1::ActionDescription& other) + : d(other.d) +{ +} + +ActionDescription& ActionDescription::operator=(const PolkitQt1::ActionDescription& other) +{ + d = other.d; + return *this; +} + +ActionDescription::~ActionDescription() +{ +} + +QString ActionDescription::actionId() const +{ + return d->actionId; +} + +QString ActionDescription::description() const +{ + return d->description; +} + +QString ActionDescription::message() const +{ + return d->message; +} + +QString ActionDescription::vendorName() const +{ + return d->vendorName; +} + +QString ActionDescription::vendorUrl() const +{ + return d->vendorUrl; +} + +QString ActionDescription::iconName() const +{ + return d->iconName; +} + +ActionDescription::ImplicitAuthorization ActionDescription::implicitAny() const +{ + return d->implicitAny; +} + +ActionDescription::ImplicitAuthorization ActionDescription::implicitInactive() const +{ + return d->implicitInactive; +} + +ActionDescription::ImplicitAuthorization ActionDescription::implicitActive() const +{ + return d->implicitActive; +} + +} diff --git a/local/recipes/libs/polkit-qt6/source/core/polkitqt1-actiondescription.h b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-actiondescription.h new file mode 100644 index 0000000000..2732727f1c --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-actiondescription.h @@ -0,0 +1,136 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + SPDX-FileCopyrightText: 2010 Dario Freddi + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef POLKITQT1_ACTION_DESCRIPTION_H +#define POLKITQT1_ACTION_DESCRIPTION_H + +#include "polkitqt1-core-export.h" + +#include +#include +#include + +typedef struct _PolkitActionDescription PolkitActionDescription; + +namespace PolkitQt1 +{ +/** + * \class ActionDescription polkitqt1-actiondescription.h ActionDescription + * \author Jaroslav Reznik + * \author Dario Freddi + * + * \brief Class used to encapsulate a registered action. + */ +class POLKITQT1_CORE_EXPORT ActionDescription +{ +public: + enum ImplicitAuthorization { + /** Unknown whether the subject is authorized, never returned in any public API. **/ + Unknown = -1, + /** Subject is not authorized. **/ + NotAuthorized = 0, + /** Authentication is required. **/ + AuthenticationRequired = 1, + /** Authentication as an administrator is required. **/ + AdministratorAuthenticationRequired = 2, + /** Authentication is required. If the authorization is obtained, it is retained. **/ + AuthenticationRequiredRetained = 3, + /** Authentication as an administrator is required. If the authorization is obtained, it is retained. **/ + AdministratorAuthenticationRequiredRetained = 4, + /** The subject is authorized. **/ + Authorized = 5 + }; + + typedef QList< ActionDescription > List; + + ActionDescription(); + /** + * \brief Constructor of ActionDescription object from PolkitActionDescription + * + * \warning Use this only if you are completely aware of what are you doing! + * + * \param actionDesciption PolkitActionDescription + */ + explicit ActionDescription(PolkitActionDescription *actionDescription); + ActionDescription(const ActionDescription &other); + ~ActionDescription(); + + ActionDescription &operator=(const ActionDescription &other); + + /** + * \brief Gets the action id for ActionDescription + * + * \return id of the action + */ + QString actionId() const; + + /** + * \brief Gets the description used for ActionDescription + * + * \return description of the action + */ + QString description() const; + + /** + * \brief Gets the message used for ActionDescription + * + * \return action message + */ + QString message() const; + + /** + * \brief Gets the vendor name for ActionDescription, if any + * + * \return vendor name + */ + QString vendorName() const; + + /** + * \brief Gets the vendor URL for ActionDescription, if any + * + * \return vendor URL or empty QString if there is no vendor URL + */ + QString vendorUrl() const; + + /** + * \brief Gets the icon name for ActionDescription, if any + * + * \return icon name or empty QString if there is no icon + */ + QString iconName() const; + + /** + * \brief Gets the implicit authorization for ActionDescription used for any subject + * + * \return A value from ImplicitAuthorization enumeration + */ + ActionDescription::ImplicitAuthorization implicitAny() const; + + /** + * \brief Gets the implicit authorization for ActionDescription used for subjects in inactive session on a local console + * + * \return A value from ImplicitAuthorization enumeration + */ + ActionDescription::ImplicitAuthorization implicitInactive() const; + + /** + * \brief Gets the implicit authorization for ActionDescription used for subjects in active session on a local console + * + * \return A value from ImplicitAuthorization enumeration + */ + ActionDescription::ImplicitAuthorization implicitActive() const; + +private: + class Data; + QSharedDataPointer< Data > d; +}; +} + +Q_DECLARE_METATYPE(PolkitQt1::ActionDescription::List) + +#endif //POLKIT_QT_ACTION_DESCRIPTION_H diff --git a/local/recipes/libs/polkit-qt6/source/core/polkitqt1-authority.cpp b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-authority.cpp new file mode 100644 index 0000000000..2f77c6d963 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-authority.cpp @@ -0,0 +1,902 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Daniel Nicoletti + SPDX-FileCopyrightText: 2009 Dario Freddi + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + SPDX-FileCopyrightText: 2009 Radek Novacek + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "polkitqt1-authority.h" + +#include +#include +#include + +#include + +namespace PolkitQt1 +{ + +class AuthorityHelper +{ +public: + AuthorityHelper() : q(nullptr) {} + ~AuthorityHelper() { + delete q; + } + Authority *q; +}; + +Q_GLOBAL_STATIC(AuthorityHelper, s_globalAuthority) + +Authority *Authority::instance(PolkitAuthority *authority) +{ + if (!s_globalAuthority()->q) { + new Authority(authority); + } + + return s_globalAuthority()->q; +} + +Authority::Result polkitResultToResult(PolkitAuthorizationResult *result) +{ + if (polkit_authorization_result_get_is_challenge(result)) { + return Authority::Challenge; + } else if (polkit_authorization_result_get_is_authorized(result)) { + return Authority::Yes; + } else { + return Authority::No; + } +} + +ActionDescription::List actionsToListAndFree(GList *glist) +{ + ActionDescription::List result; + for (GList *glist2 = glist; glist2; glist2 = g_list_next(glist2)) { + gpointer i = glist2->data; + result.append(ActionDescription(static_cast(i))); + g_object_unref(i); + } + + g_list_free(glist); + return result; +} + +class Q_DECL_HIDDEN Authority::Private +{ +public: + // Polkit will return NULL on failures, hence we use it instead of 0 + Private(Authority *qq) : q(qq) + , pkAuthority(nullptr) + , m_hasError(false) + , m_systemBus(nullptr) + { + } + + ~Private(); + + void init(); + + /** Use this method to set the error message to \p message. Set recover to \c true + * to try to reinitialize this object with init() method + */ + void setError(Authority::ErrorCode code, const QString &details = QString(), bool recover = false); + + void dbusFilter(const QDBusMessage &message); + void dbusSignalAdd(const QString &service, const QString &path, const QString &interface, const QString &name); + void seatSignalsConnect(const QString &seat); + + Authority *q; + PolkitAuthority *pkAuthority; + bool m_hasError; + Authority::ErrorCode m_lastError; + QString m_errorDetails; + // Local system bus. QDBusConnection::systemBus() may only be safely used + // inside a QCoreApplication scope as for example destruction of connected + // objects need to happen before the bus disappears. Since this class however + // is a global static and systemBus() internally is a global static we + // cannot assure destruction order. Instead we create a local copy of the + // global systemBus instance so we can make life time to our needs. + // This prevents crashes when cleaning up the global statics. + QDBusConnection *m_systemBus; + GCancellable *m_checkAuthorizationCancellable, + *m_enumerateActionsCancellable, + *m_registerAuthenticationAgentCancellable, + *m_unregisterAuthenticationAgentCancellable, + *m_authenticationAgentResponseCancellable, + *m_enumerateTemporaryAuthorizationsCancellable, + *m_revokeTemporaryAuthorizationsCancellable, + *m_revokeTemporaryAuthorizationCancellable; + + /** + * \brief Convert a Qt DetailsMap to the lower level PolkitDetails type + * + * The returned pointer needs to be freed via g_object_unref when no + * longer needed. Returns nullptr if details is empty. + */ + static PolkitDetails* convertDetailsMap(const DetailsMap &details); + static void pk_config_changed(); + static void checkAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data); + static void enumerateActionsCallback(GObject *object, GAsyncResult *result, gpointer user_data); + static void registerAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data); + static void unregisterAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data); + static void authenticationAgentResponseCallback(GObject *object, GAsyncResult *result, gpointer user_data); + static void enumerateTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data); + static void revokeTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data); + static void revokeTemporaryAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data); +}; + +Authority::Private::~Private() +{ + delete m_systemBus; + g_object_unref(m_checkAuthorizationCancellable); + g_object_unref(m_enumerateActionsCancellable); + g_object_unref(m_registerAuthenticationAgentCancellable); + g_object_unref(m_unregisterAuthenticationAgentCancellable); + g_object_unref(m_authenticationAgentResponseCancellable); + g_object_unref(m_enumerateTemporaryAuthorizationsCancellable); + g_object_unref(m_revokeTemporaryAuthorizationsCancellable); + g_object_unref(m_revokeTemporaryAuthorizationCancellable); +} + +Authority::Authority(PolkitAuthority *authority, QObject *parent) + : QObject(parent) + , d(new Private(this)) +{ + qRegisterMetaType (); + qRegisterMetaType(); + + Q_ASSERT(!s_globalAuthority()->q); + s_globalAuthority()->q = this; + + if (authority) { + d->pkAuthority = authority; + } + + d->init(); +} + +Authority::~Authority() +{ + if (d->pkAuthority != nullptr) { + g_object_unref(d->pkAuthority); + } + + delete d; +} + +void Authority::Private::init() +{ + QDBusError error; + QDBusError dbus_error; + + m_systemBus = new QDBusConnection(QDBusConnection::connectToBus(QDBusConnection::SystemBus, + QStringLiteral("polkit_qt_system_bus"))); + + m_checkAuthorizationCancellable = g_cancellable_new(); + m_enumerateActionsCancellable = g_cancellable_new(); + m_registerAuthenticationAgentCancellable = g_cancellable_new(); + m_unregisterAuthenticationAgentCancellable = g_cancellable_new(); + m_authenticationAgentResponseCancellable = g_cancellable_new(); + m_enumerateTemporaryAuthorizationsCancellable = g_cancellable_new(); + m_revokeTemporaryAuthorizationsCancellable = g_cancellable_new(); + m_revokeTemporaryAuthorizationCancellable = g_cancellable_new(); + +#ifndef POLKIT_QT_1_COMPATIBILITY_MODE + GError *gerror = nullptr; +#endif + if (pkAuthority == nullptr) { +#ifndef POLKIT_QT_1_COMPATIBILITY_MODE + pkAuthority = polkit_authority_get_sync(nullptr, &gerror); + if (gerror != nullptr) { + setError(E_GetAuthority, gerror->message); + g_error_free(gerror); + return; + } +#else + pkAuthority = polkit_authority_get(); +#endif + } + + if (pkAuthority == nullptr) { +#ifdef POLKIT_QT_1_COMPATIBILITY_MODE + (E_GetAuthority); +#endif + return; + } + + // connect changed signal + g_signal_connect(G_OBJECT(pkAuthority), "changed", G_CALLBACK(pk_config_changed), NULL); + + // need to listen to NameOwnerChanged + dbusSignalAdd("org.freedesktop.DBus", "/", "org.freedesktop.DBus", "NameOwnerChanged"); + + QString consoleKitService("org.freedesktop.ConsoleKit"); + QString consoleKitManagerPath("/org/freedesktop/ConsoleKit/Manager"); + QString consoleKitManagerInterface("org.freedesktop.ConsoleKit.Manager"); + + // first, add signals SeadAdded and SeatRemoved from ConsoleKit Manager + dbusSignalAdd(consoleKitService, consoleKitManagerPath, consoleKitManagerInterface, "SeatAdded"); + dbusSignalAdd(consoleKitService, consoleKitManagerPath, consoleKitManagerInterface, "SeatRemoved"); + + // then we need to extract all seats from ConsoleKit + QDBusMessage msg = QDBusMessage::createMethodCall(consoleKitService, consoleKitManagerPath, consoleKitManagerInterface, "GetSeats"); + const QDBusMessage reply = m_systemBus->call(msg); + + if (reply.type() != QDBusMessage::ErrorMessage && !reply.arguments().isEmpty()) { + // this method returns a list with present seats + QStringList seats; + QVariant arg = reply.arguments()[0]; + if (arg.type() == qMetaTypeId()) { + arg.value() >> seats; + } else { + seats = arg.toStringList(); + } + // it can be multiple seats present so connect all their signals + Q_FOREACH(const QString &seat, seats) { + seatSignalsConnect(seat); + } + } +} + +void Authority::Private::setError(Authority::ErrorCode code, const QString &details, bool recover) +{ + if (recover) { + init(); + } + m_lastError = code; + m_errorDetails = details; + m_hasError = true; +} + +void Authority::Private::seatSignalsConnect(const QString &seat) +{ + QString consoleKitService("org.freedesktop.ConsoleKit"); + QString consoleKitSeatInterface("org.freedesktop.ConsoleKit.Seat"); + // we want to connect to all slots of the seat + dbusSignalAdd(consoleKitService, seat, consoleKitSeatInterface, "DeviceAdded"); + dbusSignalAdd(consoleKitService, seat, consoleKitSeatInterface, "DeviceRemoved"); + dbusSignalAdd(consoleKitService, seat, consoleKitSeatInterface, "SessionAdded"); + dbusSignalAdd(consoleKitService, seat, consoleKitSeatInterface, "SessionRemoved"); + dbusSignalAdd(consoleKitService, seat, consoleKitSeatInterface, "ActiveSessionChanged"); +} + +void Authority::Private::dbusSignalAdd(const QString &service, const QString &path, const QString &interface, const QString &name) +{ + // FIXME: This code seems to be nonfunctional - it needs to be fixed somewhere (is it Qt BUG?) + m_systemBus->connect(service, path, interface, name, q, SLOT(dbusFilter(QDBusMessage))); +} + +void Authority::Private::dbusFilter(const QDBusMessage &message) +{ + if (message.type() == QDBusMessage::SignalMessage) { + Q_EMIT q->consoleKitDBChanged(); + + // TODO: Test this with the multiseat support + if (message.member() == "SeatAdded") { + seatSignalsConnect(message.arguments()[0].value().path()); + } + } +} + +bool Authority::hasError() const +{ + return d->m_hasError; +} + +Authority::ErrorCode Authority::lastError() const +{ + return d->m_lastError; +} + +const QString Authority::errorDetails() const +{ + if (d->m_lastError == E_None) { + return QString(); + } else { + return d->m_errorDetails; + } +} + +void Authority::clearError() +{ + d->m_hasError = false; + d->m_lastError = E_None; +} + +PolkitDetails* Authority::Private::convertDetailsMap(const DetailsMap &details) +{ + if (details.empty()) + return nullptr; + + auto ret = polkit_details_new(); + + for (const auto &entry: details.toStdMap()) { + const auto &key = entry.first; + const auto &value = entry.second; + + polkit_details_insert(ret, key.toUtf8().constData(), value.toUtf8().data()); + } + + return ret; +} + +void Authority::Private::pk_config_changed() +{ + Q_EMIT Authority::instance()->configChanged(); +} + +PolkitAuthority *Authority::polkitAuthority() const +{ + return d->pkAuthority; +} + +Authority::Result Authority::checkAuthorizationSyncWithDetails(const QString &actionId, const Subject &subject, AuthorizationFlags flags, const DetailsMap &details) +{ + PolkitAuthorizationResult *pk_result; + GError *error = nullptr; + + if (Authority::instance()->hasError()) { + return Unknown; + } + + if (!subject.isValid()) { + d->setError(E_WrongSubject); + return Unknown; + } + + auto pk_details = Authority::Private::convertDetailsMap(details); + + pk_result = polkit_authority_check_authorization_sync(d->pkAuthority, + subject.subject(), + actionId.toLatin1().data(), + pk_details, + (PolkitCheckAuthorizationFlags)(int)flags, + nullptr, + &error); + + if (pk_details) { + g_object_unref(pk_details); + } + + if (error != nullptr) { + d->setError(E_CheckFailed, error->message); + g_error_free(error); + return Unknown; + } + + if (!pk_result) { + d->setError(E_UnknownResult); + return Unknown; + } else { + Authority::Result res = polkitResultToResult(pk_result); + g_object_unref(pk_result); + return res; + } +} + +Authority::Result Authority::checkAuthorizationSync(const QString &actionId, const Subject &subject, AuthorizationFlags flags) +{ + return checkAuthorizationSyncWithDetails(actionId, subject, flags, DetailsMap()); +} + +void Authority::checkAuthorizationWithDetails(const QString &actionId, const Subject &subject, AuthorizationFlags flags, const DetailsMap &details) +{ + if (Authority::instance()->hasError()) { + return; + } + + if (!subject.isValid()) { + d->setError(E_WrongSubject); + return; + } + + auto pk_details = Authority::Private::convertDetailsMap(details); + + polkit_authority_check_authorization(d->pkAuthority, + subject.subject(), + actionId.toLatin1().data(), + pk_details, + (PolkitCheckAuthorizationFlags)(int)flags, + d->m_checkAuthorizationCancellable, + d->checkAuthorizationCallback, this); + + if (pk_details) { + g_object_unref(pk_details); + } +} + +void Authority::checkAuthorization(const QString &actionId, const Subject &subject, AuthorizationFlags flags) +{ + checkAuthorizationWithDetails(actionId, subject, flags, DetailsMap()); +} + +void Authority::Private::checkAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data) +{ + Authority *authority = (Authority *) user_data; + + Q_ASSERT(authority != nullptr); + + GError *error = nullptr; + PolkitAuthorizationResult *pkResult = polkit_authority_check_authorization_finish((PolkitAuthority *) object, result, &error); + + if (error != nullptr) { + // We don't want to set error if this is cancellation of some action + if (error->code != 1) { + authority->d->setError(E_CheckFailed, error->message); + } + g_error_free(error); + return; + } + if (pkResult != nullptr) { + Q_EMIT authority->checkAuthorizationFinished(polkitResultToResult(pkResult)); + g_object_unref(pkResult); + } else { + authority->d->setError(E_UnknownResult); + } +} + +void Authority::checkAuthorizationCancel() +{ + if (!g_cancellable_is_cancelled(d->m_checkAuthorizationCancellable)) { + g_cancellable_cancel(d->m_checkAuthorizationCancellable); + } +} + +ActionDescription::List Authority::enumerateActionsSync() +{ + if (Authority::instance()->hasError()) { + return ActionDescription::List(); + } + + GError *error = nullptr; + + GList *glist = polkit_authority_enumerate_actions_sync(d->pkAuthority, + nullptr, + &error); + + if (error != nullptr) { + d->setError(E_EnumFailed, error->message); + g_error_free(error); + return ActionDescription::List(); + } + + return actionsToListAndFree(glist); +} + +void Authority::enumerateActions() +{ + if (Authority::instance()->hasError()) { + return; + } + + polkit_authority_enumerate_actions(d->pkAuthority, + d->m_enumerateActionsCancellable, + d->enumerateActionsCallback, + Authority::instance()); +} + +void Authority::Private::enumerateActionsCallback(GObject *object, GAsyncResult *result, gpointer user_data) +{ + Authority *authority = (Authority *) user_data; + Q_ASSERT(authority != nullptr); + GError *error = nullptr; + GList *list = polkit_authority_enumerate_actions_finish((PolkitAuthority *) object, result, &error); + if (error != nullptr) { + // We don't want to set error if this is cancellation of some action + if (error->code != 1) { + authority->d->setError(E_EnumFailed, error->message); + } + g_error_free(error); + return; + } + + Q_EMIT authority->enumerateActionsFinished(actionsToListAndFree(list)); +} + +void Authority::enumerateActionsCancel() +{ + if (!g_cancellable_is_cancelled(d->m_enumerateActionsCancellable)) { + g_cancellable_cancel(d->m_enumerateActionsCancellable); + } +} + +bool Authority::registerAuthenticationAgentSync(const Subject &subject, const QString &locale, const QString &objectPath) +{ + if (Authority::instance()->hasError()) { + return false; + } + + gboolean result; + GError *error = nullptr; + + if (!subject.isValid()) { + d->setError(E_WrongSubject); + return false; + } + + result = polkit_authority_register_authentication_agent_sync(d->pkAuthority, + subject.subject(), locale.toLatin1().data(), + objectPath.toLatin1().data(), nullptr, &error); + + if (error) { + d->setError(E_RegisterFailed, error->message); + g_error_free(error); + return false; + } + + return result; +} + +void Authority::registerAuthenticationAgent(const Subject &subject, const QString &locale, const QString &objectPath) +{ + if (Authority::instance()->hasError()) { + return; + } + + if (!subject.isValid()) { + d->setError(E_WrongSubject); + return; + } + + polkit_authority_register_authentication_agent(d->pkAuthority, + subject.subject(), + locale.toLatin1().data(), + objectPath.toLatin1().data(), + d->m_registerAuthenticationAgentCancellable, + d->registerAuthenticationAgentCallback, + this); +} + +void Authority::Private::registerAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data) +{ + Authority *authority = (Authority *) user_data; + Q_ASSERT(authority != nullptr); + GError *error = nullptr; + bool res = polkit_authority_register_authentication_agent_finish((PolkitAuthority *) object, result, &error); + if (error != nullptr) { + // We don't want to set error if this is cancellation of some action + if (error->code != 1) { + authority->d->setError(E_EnumFailed , error->message); + } + g_error_free(error); + return; + } + + Q_EMIT authority->registerAuthenticationAgentFinished(res); +} + +void Authority::registerAuthenticationAgentCancel() +{ + if (!g_cancellable_is_cancelled(d->m_registerAuthenticationAgentCancellable)) { + g_cancellable_cancel(d->m_registerAuthenticationAgentCancellable); + } +} + +bool Authority::unregisterAuthenticationAgentSync(const Subject &subject, const QString &objectPath) +{ + if (d->pkAuthority) { + return false; + } + + if (!subject.isValid()) { + d->setError(E_WrongSubject); + return false; + } + + GError *error = nullptr; + + bool result = polkit_authority_unregister_authentication_agent_sync(d->pkAuthority, + subject.subject(), + objectPath.toUtf8().data(), + nullptr, + &error); + + if (error != nullptr) { + d->setError(E_UnregisterFailed, error->message); + g_error_free(error); + return false; + } + + return result; +} + +void Authority::unregisterAuthenticationAgent(const Subject &subject, const QString &objectPath) +{ + if (Authority::instance()->hasError()) { + return; + } + + if (!subject.isValid()) { + d->setError(E_WrongSubject); + return; + } + + polkit_authority_unregister_authentication_agent(d->pkAuthority, + subject.subject(), + objectPath.toUtf8().data(), + d->m_unregisterAuthenticationAgentCancellable, + d->unregisterAuthenticationAgentCallback, + this); +} + +void Authority::Private::unregisterAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data) +{ + Authority *authority = (Authority *) user_data; + Q_ASSERT(authority); + GError *error = nullptr; + bool res = polkit_authority_unregister_authentication_agent_finish((PolkitAuthority *) object, result, &error); + if (error != nullptr) { + // We don't want to set error if this is cancellation of some action + if (error->code != 1) { + authority->d->setError(E_UnregisterFailed, error->message); + } + g_error_free(error); + return; + } + + Q_EMIT authority->unregisterAuthenticationAgentFinished(res); +} + +void Authority::unregisterAuthenticationAgentCancel() +{ + if (!g_cancellable_is_cancelled(d->m_unregisterAuthenticationAgentCancellable)) { + g_cancellable_cancel(d->m_unregisterAuthenticationAgentCancellable); + } +} + +bool Authority::authenticationAgentResponseSync(const QString &cookie, const Identity &identity) +{ + if (Authority::instance()->hasError()) { + return false; + } + + if (cookie.isEmpty() || !identity.isValid()) { + d->setError(E_CookieOrIdentityEmpty); + return false; + } + + GError *error = nullptr; + + bool result = polkit_authority_authentication_agent_response_sync(d->pkAuthority, + cookie.toUtf8().data(), + identity.identity(), + nullptr, + &error); + if (error != nullptr) { + d->setError(E_AgentResponseFailed, error->message); + g_error_free(error); + return false; + } + + return result; +} + +void Authority::authenticationAgentResponse(const QString &cookie, const Identity &identity) +{ + if (Authority::instance()->hasError()) { + return; + } + + if (cookie.isEmpty() || !identity.isValid()) { + d->setError(E_CookieOrIdentityEmpty); + return; + } + + polkit_authority_authentication_agent_response(d->pkAuthority, + cookie.toUtf8().data(), + identity.identity(), + d->m_authenticationAgentResponseCancellable, + d->authenticationAgentResponseCallback, + this); +} + +void Authority::Private::authenticationAgentResponseCallback(GObject *object, GAsyncResult *result, gpointer user_data) +{ + Authority *authority = (Authority *) user_data; + Q_ASSERT(authority); + GError *error = nullptr; + bool res = polkit_authority_authentication_agent_response_finish((PolkitAuthority *) object, result, &error); + if (error != nullptr) { + // We don't want to set error if this is cancellation of some action + if (error->code != 1) { + authority->d->setError(E_AgentResponseFailed, error->message); + } + g_error_free(error); + return; + } + + Q_EMIT authority->authenticationAgentResponseFinished(res); +} + +void Authority::authenticationAgentResponseCancel() +{ + if (!g_cancellable_is_cancelled(d->m_authenticationAgentResponseCancellable)) { + g_cancellable_cancel(d->m_authenticationAgentResponseCancellable); + } +} + +TemporaryAuthorization::List Authority::enumerateTemporaryAuthorizationsSync(const Subject &subject) +{ + TemporaryAuthorization::List result; + + GError *error = nullptr; + GList *glist = polkit_authority_enumerate_temporary_authorizations_sync(d->pkAuthority, + subject.subject(), + nullptr, + &error); + if (error != nullptr) { + d->setError(E_EnumFailed, error->message); + g_error_free(error); + return result; + } + + GList *glist2; + for (glist2 = glist; glist2 != nullptr; glist2 = g_list_next(glist2)) { + result.append(TemporaryAuthorization((PolkitTemporaryAuthorization *) glist2->data)); + } + + g_list_free(glist); + + return result; +} + +void Authority::Private::enumerateTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data) +{ + Authority *authority = (Authority *) user_data; + Q_ASSERT(authority); + GError *error = nullptr; + + GList *glist = polkit_authority_enumerate_temporary_authorizations_finish((PolkitAuthority *) object, result, &error); + + if (error != nullptr) { + // We don't want to set error if this is cancellation of some action + if (error->code != 1) { + authority->d->setError(E_EnumFailed, error->message); + } + g_error_free(error); + return; + } + TemporaryAuthorization::List res; + GList *glist2; + for (glist2 = glist; glist2 != nullptr; glist2 = g_list_next(glist2)) { + res.append(TemporaryAuthorization((PolkitTemporaryAuthorization *) glist2->data)); + } + + g_list_free(glist); + + Q_EMIT authority->enumerateTemporaryAuthorizationsFinished(res); +} + +void Authority::enumerateTemporaryAuthorizationsCancel() +{ + if (!g_cancellable_is_cancelled(d->m_enumerateTemporaryAuthorizationsCancellable)) { + g_cancellable_cancel(d->m_enumerateTemporaryAuthorizationsCancellable); + } +} + +bool Authority::revokeTemporaryAuthorizationsSync(const Subject &subject) +{ + bool result; + if (Authority::instance()->hasError()) { + return false; + } + + GError *error = nullptr; + result = polkit_authority_revoke_temporary_authorizations_sync(d->pkAuthority, + subject.subject(), + nullptr, + &error); + if (error != nullptr) { + d->setError(E_RevokeFailed, error->message); + g_error_free(error); + return false; + } + return result; +} + +void Authority::revokeTemporaryAuthorizations(const Subject &subject) +{ + if (Authority::instance()->hasError()) { + return; + } + + polkit_authority_revoke_temporary_authorizations(d->pkAuthority, + subject.subject(), + d->m_revokeTemporaryAuthorizationsCancellable, + d->revokeTemporaryAuthorizationsCallback, + this); +} + +void Authority::Private::revokeTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data) +{ + Authority *authority = (Authority *) user_data; + Q_ASSERT(authority != nullptr); + GError *error = nullptr; + + bool res = polkit_authority_revoke_temporary_authorizations_finish((PolkitAuthority *) object, result, &error); + + if (error != nullptr) { + // We don't want to set error if this is cancellation of some action + if (error->code != 1) { + authority->d->setError(E_RevokeFailed, error->message); + } + g_error_free(error); + return; + } + + Q_EMIT authority->revokeTemporaryAuthorizationsFinished(res); +} + +void Authority::revokeTemporaryAuthorizationsCancel() +{ + if (!g_cancellable_is_cancelled(d->m_revokeTemporaryAuthorizationsCancellable)) { + g_cancellable_cancel(d->m_revokeTemporaryAuthorizationsCancellable); + } +} + +bool Authority::revokeTemporaryAuthorizationSync(const QString &id) +{ + bool result; + if (Authority::instance()->hasError()) { + return false; + } + + GError *error = nullptr; + result = polkit_authority_revoke_temporary_authorization_by_id_sync(d->pkAuthority, + id.toUtf8().data(), + nullptr, + &error); + if (error != nullptr) { + d->setError(E_RevokeFailed, error->message); + g_error_free(error); + return false; + } + return result; +} + +void Authority::revokeTemporaryAuthorization(const QString &id) +{ + if (Authority::instance()->hasError()) { + return; + } + + polkit_authority_revoke_temporary_authorization_by_id(d->pkAuthority, + id.toUtf8().data(), + d->m_revokeTemporaryAuthorizationCancellable, + d->revokeTemporaryAuthorizationCallback, + this); +} + +void Authority::Private::revokeTemporaryAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data) +{ + Authority *authority = (Authority *) user_data; + Q_ASSERT(authority != nullptr); + GError *error = nullptr; + + bool res = polkit_authority_revoke_temporary_authorization_by_id_finish((PolkitAuthority *) object, result, &error); + + if (error != nullptr) { + // We don't want to set error if this is cancellation of some action + if (error->code != 1) { + authority->d->setError(E_RevokeFailed, error->message); + } + g_error_free(error); + return; + } + + Q_EMIT authority->revokeTemporaryAuthorizationFinished(res); +} + +void Authority::revokeTemporaryAuthorizationCancel() +{ + if (!g_cancellable_is_cancelled(d->m_revokeTemporaryAuthorizationCancellable)) { + g_cancellable_cancel(d->m_revokeTemporaryAuthorizationCancellable); + } +} + +} + +#include "moc_polkitqt1-authority.cpp" diff --git a/local/recipes/libs/polkit-qt6/source/core/polkitqt1-authority.h b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-authority.h new file mode 100644 index 0000000000..d2d66ba345 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-authority.h @@ -0,0 +1,550 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Daniel Nicoletti + SPDX-FileCopyrightText: 2009 Dario Freddi + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + SPDX-FileCopyrightText: 2009 Radek Novacek + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef POLKITQT1_AUTHORITY_H +#define POLKITQT1_AUTHORITY_H + +#include "polkitqt1-core-export.h" +#include "polkitqt1-identity.h" +#include "polkitqt1-subject.h" +#include "polkitqt1-temporaryauthorization.h" +#include "polkitqt1-actiondescription.h" + +#include +#include +#include + +typedef struct _PolkitAuthority PolkitAuthority; + +/** + * \namespace PolkitQt1 PolkitQt + * + * \brief Namespace wrapping Polkit-Qt classes + * + * This namespace wraps all Polkit-Qt classes. + */ +namespace PolkitQt1 +{ + +typedef QMap DetailsMap; + +/** + * \class Authority polkitqt1-authority.h Authority + * \author Daniel Nicoletti + * \author Dario Freddi + * \author Jaroslav Reznik + * + * \brief Convenience class for Qt/KDE applications + * + * This class is a singleton that provides makes easy the usage + * of PolKitAuthority. It emits configChanged() + * whenever PolicyKit files change (e.g. the PolicyKit.conf + * or .policy files) or when ConsoleKit reports activities changes. + * + * \note This class is a singleton, its constructor is private. + * Call Authority::instance() to get an instance of the Authority object. + * Do not delete Authority::instance(), cleanup will be done automatically. + */ +class POLKITQT1_CORE_EXPORT Authority : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(Authority) +public: + enum Result { + /** Result unknown */ + Unknown = 0x00, + /** The subject is authorized for the specified action */ + Yes = 0x01, + /** The subject is not authorized for the specified action */ + No = 0x02, + /** The subject is authorized if more information is provided */ + Challenge = 0x03 + }; + Q_ENUM(Result) + + enum AuthorizationFlag { + /** No flags set **/ + None = 0x00, + /** If the subject can obtain the authorization through authentication, + * and an authentication agent is available, then attempt to do so. + * + * Note, this means that the method used for checking authorization is likely + * to block for a long time. **/ + AllowUserInteraction = 0x01 + }; + Q_DECLARE_FLAGS(AuthorizationFlags, AuthorizationFlag) + + /** Error codes for the authority class */ + enum ErrorCode { + /** No error occurred **/ + E_None = 0x00, + /** Authority cannot be obtained **/ + E_GetAuthority = 0x01, + /** Authority check failed **/ + E_CheckFailed = 0x02, + /** Wrong or empty subject was given **/ + E_WrongSubject = 0x03, + /** Action returned unknown result **/ + E_UnknownResult = 0x04, + /** Enumerating actions failed **/ + E_EnumFailed = 0x05, + /** Registration of authentication agent failed **/ + E_RegisterFailed = 0x06, + /** Unregistration of authentication agent failed **/ + E_UnregisterFailed = 0x07, + /** Cookie or polkitqt1-identity.handled to the action is empty **/ + E_CookieOrIdentityEmpty = 0x08, + /** Response of auth agent failed **/ + E_AgentResponseFailed = 0x09, + /** Revoke temporary authorizations failed **/ + E_RevokeFailed = 0x0A + }; + Q_ENUM(ErrorCode) + + /** + * \brief Returns the instance of Authority + * + * Returns the current instance of Authority. Call this function whenever + * you need to access the Authority class. + * + * \note Authority is a singleton. Memory is handled by polkit-qt, so you just + * need to call this function to get a working instance of Authority. + * Don't delete the object after having used it. + * + * \param authority use this if you want to set an explicit PolkitAuthority. If you + * don't know what this implies, simply ignore the parameter. In case + * you want to use it, be sure of streaming it the first time you call + * this function, otherwise it will have no effect. + * + * \return The current authority instance + */ + static Authority *instance(PolkitAuthority *authority = nullptr); + + ~Authority() override; + + /** + * You should always call this method after every action. No action will be allowed + * if the object is in error state. Use clearError() to clear the error message. + * + * \see lastError + * \see clearError + * + * \return \c true if an error occurred, \c false if the library is ready + */ + bool hasError() const; + + /** + * \return the code of last error + */ + ErrorCode lastError() const; + + /** + * Get detail information about error that occurred. + * + * \return detail message + */ + const QString errorDetails() const; + + /** + * Use this method to clear the error message. + */ + void clearError(); + + /** + * Returns the current instance of PolkitAuthority. If you are handling + * it through Polkit-qt (which is quite likely, since you are calling + * this function), DO NOT use any PolicyKit API's specific method that + * modifies the instance on it, unless you're completely aware of what you're doing and + * of the possible consequencies. Use this instance only to gather information. + * + * \return the current PolkitAuthority instance + */ + PolkitAuthority *polkitAuthority() const; + + /** + * This function should be used by mechanisms (e.g.: helper applications). + * It returns the action should be carried out, so if the caller was + * actually authorized to perform it. The result is in form of a Result, so that + * you can have more control over the whole process, and detect an eventual error. + * Most of the times you simply want to check if the result is == to \c Result::Yes, + * if you don't have specific needs. + * + * It is CRITICAL that you call this function + * and check what it returns before doing anything in your helper, since otherwise + * you could be actually performing an action from an unknown or unauthorized caller. + * + * When operation is finished, signal checkAuthorizationFinish is emitted + * with result of authorization check in its parameter. + * + * \see checkAuthorizationSync Synchronous version of this method. + * \see checkAuthorizationFinished Signal that is emitted when this method finishes. + * \see checkAuthorizationCancel Use it to cancel execution of this method. + * + * \param actionId the Id of the action in question + * \param subject subject that the action is authorized for (e.g. unix process) + * \param flags flags that influences the authorization checking + */ + void checkAuthorization(const QString &actionId, const Subject &subject, + AuthorizationFlags flags); + + /** + * This function does the same as checkAuthorization(const QString&, const + * Subject&, AuthorizationFlags), but also accepts a + * DetailsMap parameter. This map can contain key/value pairs that, for + * example, are used to expand placeholders in polkit authentication + * messages that are formatted like "Authentication required to access + * $(device)". For this example, when a key "device" exists in the map, + * the "$(device)" will be replaced by the corresponding value in the map. + * + * \see checkAuthorization(const QString&, const Subject&, AuthorizationFlags) Base version of this method. + */ + // TODO: merge with checkAuthorization when we decide to break binary compatibility probably in Plasma 6 + void checkAuthorizationWithDetails( + const QString &actionId, const Subject &subject, + AuthorizationFlags flags, const DetailsMap &details); + + /** + * Synchronous version of the checkAuthorization method. + * + * \param actionId the Id of the action in question + * \param subject subject that the action is authorized for (e.g. unix process) + * \param flags flags that influences the authorization checking + * + * \see checkAuthorization Asynchronous version of this method. + */ + Result checkAuthorizationSync(const QString &actionId, const Subject &subject, + AuthorizationFlags flags); + + /** + * This function does the same as checkAuthorizationSync(const QString&, + * const Subject&, AuthorizationFlags), but also accepts a DetailsMap + * parameter. + * + * \see checkAuthorization(const QString&, const Subject&, AuthorizationFlags, const DetailsMap&) for a description of the details parameter. + * + * \see checkAuthorizationSync(const QString&, const Subject, AuthorizationFlags) Base version of this method. + */ + Result checkAuthorizationSyncWithDetails(const QString &actionId, const Subject &subject, + AuthorizationFlags flags, const DetailsMap &details); + + /** + * This method can be used to cancel last authorization check. + */ + void checkAuthorizationCancel(); + + /** + * Asynchronously retrieves all registered actions. + * + * When operation is finished, signal checkAuthorizationFinish is emitted + * with result of authorization check in its parameter. + * + * \see enumerateActionsSync Synchronous version of this method. + * \see enumerateActionsFinished Signal that is emitted when this method finishes. + * \see enumerateActionsCancel Use it to cancel execution of this method. + */ + void enumerateActions(); + + /** + * Synchronously retrieves all registered actions. + * + * \see enumerateActions Asynchronous version of this method. + * + * \return a list of Action IDs + */ + ActionDescription::List enumerateActionsSync(); + + /** + * This method can be used to cancel enumeration of actions + */ + void enumerateActionsCancel(); + + /** + * Registers an authentication agent. + * + * \see registerAuthenticationAgentSync Synchronous version of this method. + * \see registerAuthenticationAgentFinished Signal that is emitted when this method finishes. + * \see registerAuthenticationAgentCancel Use it to cancel execution of this method. + * + * \param subject caller subject + * \param locale the locale of the authentication agent + * \param objectPath the object path for the authentication agent + */ + void registerAuthenticationAgent(const Subject &subject, const QString &locale, + const QString &objectPath); + + /** + * Registers an authentication agent. + * + * \see registerAuthenticationAgent Asynchronous version of this method. + * + * \param subject caller subject + * \param locale the locale of the authentication agent + * \param objectPath the object path for the authentication agent + * + * \return \c true if the Authentication agent has been successfully registered + * \c false if the Authentication agent registration failed + */ + bool registerAuthenticationAgentSync(const Subject &subject, const QString &locale, + const QString &objectPath); + + /** + * This method can be used to cancel the registration of the authentication agent. + */ + void registerAuthenticationAgentCancel(); + + /** + * Unregisters an Authentication agent. + * + * \see unregisterAuthenticationAgentSync Synchronous version of this method. + * \see unregisterAuthenticationAgentFinished Signal that is emitted when this method finishes. + * \see unregisterAuthenticationAgentCancel Use it to cancel execution of this method. + * + * \param subject caller subject + * \param objectPath the object path for the Authentication agent + * + * \return \c true if the Authentication agent has been successfully unregistered + * \c false if the Authentication agent unregistration failed + */ + void unregisterAuthenticationAgent(const Subject &subject, const QString &objectPath); + + /** + * Unregisters an Authentication agent. + * + * \see unregisterAuthenticationAgent Asynchronous version of this method. + * + * \param subject caller subject + * \param objectPath the object path for the Authentication agent + * + * \return \c true if the Authentication agent has been successfully unregistered + * \c false if the Authentication agent unregistration failed + */ + bool unregisterAuthenticationAgentSync(const Subject &subject, const QString &objectPath); + + /** + * This method can be used to cancel the unregistration of the authentication agent. + */ + void unregisterAuthenticationAgentCancel(); + + /** + * Provide response that \p identity successfully authenticated for the authentication request identified by \p cookie. + * + * \see authenticationAgentResponseSync Synchronous version of this method. + * \see authenticationAgentResponseFinished Signal that is emitted when this method finishes. + * \see authenticationAgentResponseCancel Use it to cancel execution of this method. + * + * \param cookie The cookie passed to the authentication agent from the authority. + * \param identity The identity that was authenticated. + */ + void authenticationAgentResponse(const QString &cookie, const Identity &identity); + + /** + * Provide response that \p identity successfully authenticated for the authentication request identified by \p cookie. + * + * \see authenticationAgentResponse Asynchronous version of this method. + * + * \param cookie The cookie passed to the authentication agent from the authority. + * \param identity The identity that was authenticated. + * + * \return \c true if authority acknowledged the call, \c false if error is set. + * + */ + bool authenticationAgentResponseSync(const QString& cookie, const PolkitQt1::Identity& identity); + + /** + * This method can be used to cancel the authenticationAgentResponseAsync method. + */ + void authenticationAgentResponseCancel(); + + /** + * Retrieves all temporary action that applies to \p subject. + * + * \see enumerateTemporaryAuthorizationsSync Synchronous version of this method. + * \see enumerateTemporaryAuthorizationsFinished Signal that is emitted when this method finishes. + * \see enumerateTemporaryAuthorizationsCancel Use it to cancel execution of this method. + * + * \param subject the subject to get temporary authorizations for + * + */ + void enumerateTemporaryAuthorizations(const Subject &subject); + + /** + * Retrieves all temporary action that applies to \p subject + * + * \see enumerateTemporaryAuthorizations Asynchronous version of this method. + * + * \param subject the subject to get temporary authorizations for + * + * \note Free all TemporaryAuthorization objects using \p delete operator. + * + * \return List of all temporary authorizations + */ + TemporaryAuthorization::List enumerateTemporaryAuthorizationsSync(const Subject &subject); + + /** + * This method can be used to cancel the enumerateTemporaryAuthorizationsAsync method. + */ + void enumerateTemporaryAuthorizationsCancel(); + + /** + * Revokes all temporary authorizations that applies to \p subject + * + * \see revokeTemporaryAuthorizationsSync Synchronous version of this method. + * \see revokeTemporaryAuthorizationsFinished Signal that is emitted when this method finishes. + * \see revokeTemporaryAuthorizationsCancel Use it to cancel execution of this method. + + * \param subject the subject to revoke temporary authorizations from + */ + void revokeTemporaryAuthorizations(const Subject &subject); + + /** + * Revokes all temporary authorizations that applies to \p subject + * + * \see revokeTemporaryAuthorizations Asynchronous version of this method. + * + * \param subject the subject to revoke temporary authorizations from + * + * \return \c true if all temporary authorization were revoked + * \c false if the revoking failed + */ + bool revokeTemporaryAuthorizationsSync(const Subject &subject); + + /** + * This method can be used to cancel the method revokeTemporaryAuthorizationsAsync. + */ + void revokeTemporaryAuthorizationsCancel(); + + /** + * Revokes temporary authorization by \p id + * + * \see revokeTemporaryAuthorizationSync Synchronous version of this method. + * \see revokeTemporaryAuthorizationFinished Signal that is emitted when this method finishes. + * \see revokeTemporaryAuthorizationCancel Use it to cancel execution of this method. + * + * \param id the identifier of the temporary authorization + */ + void revokeTemporaryAuthorization(const QString &id); + + /** + * Revokes temporary authorization by \p id + * + * \see revokeTemporaryAuthorization Asynchronous version of this method. + * + * \param id the identifier of the temporary authorization + * + * \return \c true if the temporary authorization was revoked + * \c false if the revoking failed + */ + bool revokeTemporaryAuthorizationSync(const QString &id); + + /** + * This method can be used to cancel the method revokeTemporaryAuthorizationAsync. + */ + void revokeTemporaryAuthorizationCancel(); + +Q_SIGNALS: + /** + * This signal will be emitted when a configuration + * file gets changed (e.g. /etc/PolicyKit/PolicyKit.conf or + * .policy files). + * Connect to this signal if you want to track down + * actions. + */ + void configChanged(); + + /** + * This signal is emitted when ConsoleKit configuration + * changes. This might happen when a session becomes active + * or inactive. + * + * If you want to track your actions directly you should + * connect to this signal, as this might change the return value + * PolicyKit will give you. + * + * \note If you use Action you'll probably prefer to + * use the dataChanged() signal to track Action changes. + */ + void consoleKitDBChanged(); + + /** + * This signal is emitted when asynchronous method checkAuthorization finishes. + * + * The argument is the result of authorization. + */ + void checkAuthorizationFinished(PolkitQt1::Authority::Result); + + /** + * This signal is emitted when asynchronous method enumerateActions finishes. + * + * The argument is the list of all Action IDs. + */ + void enumerateActionsFinished(PolkitQt1::ActionDescription::List); + + /** + * This signal is emitted when asynchronous method registerAuthenticationAgent finishes. + * + * The argument is \c true if the Authentication agent has been successfully registered + * \c false if the Authentication agent registration failed + */ + void registerAuthenticationAgentFinished(bool); + + /** + * This signal is emitted when asynchronous method unregisterAuthenticationAgent finishes. + * + * The argument is \c true if the Authentication agent has been successfully unregistered + * \c false if the Authentication agent unregistration failed + */ + void unregisterAuthenticationAgentFinished(bool); + + /** + * This signal is emitted when asynchronous method authenticationAgentResponse finishes. + * + * The argument is \c true if authority acknowledged the call, \c false if error is set. + */ + void authenticationAgentResponseFinished(bool); + + /** + * This signal is emitted when asynchronous method enumerateTemporaryAuthorizations finishes. + * + * The argument is list of all temporary authorizations. + * + * \note Free all TemporaryAuthorization objects using \p delete operator. + */ + void enumerateTemporaryAuthorizationsFinished(PolkitQt1::TemporaryAuthorization::List); + + /** + * This signal is emitted when asynchronous method revokeTemporaryAuthorizations finishes. + * + * The argument is \c true if all temporary authorizations were revoked + * \c false if the revoking failed + */ + void revokeTemporaryAuthorizationsFinished(bool); + + /** + * This signal is emitted when asynchronous method revokeTemporaryAuthorization finishes. + * \return \c true if the temporary authorization was revoked + * \c false if the revoking failed + */ + void revokeTemporaryAuthorizationFinished(bool); + +private: + explicit Authority(PolkitAuthority *context, QObject *parent = nullptr); + + class Private; + friend class Private; + Private * const d; + + Q_PRIVATE_SLOT(d, void dbusFilter(const QDBusMessage &message)) +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(Authority::AuthorizationFlags) + +} + +#endif diff --git a/local/recipes/libs/polkit-qt6/source/core/polkitqt1-details.cpp b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-details.cpp new file mode 100644 index 0000000000..b5be7ee66c --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-details.cpp @@ -0,0 +1,94 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Radek Novacek + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "polkitqt1-details.h" + +#include + +#include + +namespace PolkitQt1 +{ + +class Q_DECL_HIDDEN Details::Data : public QSharedData +{ +public: + Data() {} + Data(const Data &other) + : QSharedData(other) + , polkitDetails(other.polkitDetails) + { + if (polkitDetails != nullptr) { + g_object_ref(polkitDetails); + } + } + ~Data() + { + if (polkitDetails != nullptr) { + g_object_unref(polkitDetails); + } + } + + PolkitDetails *polkitDetails; +}; + +Details::Details() + : d(new Data) +{ + d->polkitDetails = polkit_details_new(); +} + +Details::Details(PolkitDetails *pkDetails) + : d(new Data) +{ + d->polkitDetails = pkDetails; + + if (d->polkitDetails != nullptr) { + g_object_ref(d->polkitDetails); + } +} + +Details::~Details() +{ +} + +Details::Details(const Details &other) = default; + +Details& Details::operator=(const PolkitQt1::Details& other) +{ + d = other.d; + return *this; +} + +QString Details::lookup(const QString &key) const +{ + const gchar *result = polkit_details_lookup(d->polkitDetails, key.toUtf8().data()); + if (result != nullptr) { + return QString::fromUtf8(result); + } else { + return QString(); + } +} + +void Details::insert(const QString &key, const QString &value) +{ + polkit_details_insert(d->polkitDetails, key.toUtf8().data(), value.toUtf8().data()); +} + +QStringList Details::keys() const +{ + gchar **result = polkit_details_get_keys(d->polkitDetails); + QStringList list; + int len = g_strv_length(result); + for (int i = 0; i < len; i++) { + list.append(QString::fromUtf8(result[i])); + } + g_strfreev(result); + return list; +} + +} diff --git a/local/recipes/libs/polkit-qt6/source/core/polkitqt1-details.h b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-details.h new file mode 100644 index 0000000000..59dfcb6d77 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-details.h @@ -0,0 +1,89 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Radek Novacek + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef POLKITQT1_DETAILS_H +#define POLKITQT1_DETAILS_H + +#include "polkitqt1-core-export.h" + +#include +#include + +typedef struct _PolkitDetails PolkitDetails; + +/** + * \namespace PolkitQt1 PolkitQt + * + * \brief Namespace wrapping Polkit-Qt classes + * + * This namespace wraps all Polkit-Qt classes. + */ +namespace PolkitQt1 +{ + +/** + * \class Details polkitqt1-details.h Details + * \author Radek Novacek + * + * \brief Class used for passing details around. + */ +class POLKITQT1_CORE_EXPORT Details +{ +public: + /** + * Creates a new Details object + */ + Details(); + + /** + * Creates Details object from PolkitDetails + * + * \warning Use this only if you are completely aware of what are you doing! + * + * \param pkDetails PolkitDetails object + */ + explicit Details(PolkitDetails *pkDetails); + + /** + * Copy constructor. + */ + Details(const Details &other); + + ~Details(); + + Details &operator=(const Details &other); + + /** + * Get the value for \p key + * + * \param key A key + * \return Value of the key \p key, otherwise empty QString. + */ + QString lookup(const QString &key) const; + + /** + * Inserts key \p key with value \p value. + * + * \param key A key. + * \param value A value. + */ + void insert(const QString &key, const QString &value); + + /** + * Gets a list of all keys. + * + * \return List of all keys. + */ + QStringList keys() const; +private: + class Data; + QExplicitlySharedDataPointer< Data > d; +}; + +} + +#endif // DETAILS_H diff --git a/local/recipes/libs/polkit-qt6/source/core/polkitqt1-identity.cpp b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-identity.cpp new file mode 100644 index 0000000000..24584b86bc --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-identity.cpp @@ -0,0 +1,212 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Lukas Tinkl + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "polkitqt1-identity.h" + +#include + +#include + +namespace PolkitQt1 +{ + +class Q_DECL_HIDDEN Identity::Data : public QSharedData +{ +public: + Data() : identity(nullptr) {} + Data(const Data& other) + : QSharedData(other) + , identity(other.identity) + { + if (identity) { + g_object_ref(identity); + } + } + ~Data() + { + if (identity) { + g_object_unref(identity); + } + } + + PolkitIdentity *identity; +}; + +Identity::Identity() + : d(new Data) +{ +} + +Identity::Identity(PolkitIdentity *polkitIdentity) + : d(new Data) +{ + d->identity = polkitIdentity; + + if (d->identity) { + g_object_ref(d->identity); + } +} + +Identity::Identity(const PolkitQt1::Identity& other) + : d(other.d) +{ + +} + +Identity::~Identity() +{ +} + +Identity& Identity::operator=(const PolkitQt1::Identity& other) +{ + d = other.d; + return *this; +} + +bool Identity::isValid() const +{ + return d->identity != nullptr; +} + +PolkitIdentity *Identity::identity() const +{ + return d->identity; +} + +void Identity::setIdentity(PolkitIdentity *identity) +{ + if (d->identity == identity) { + return; + } + + if (d->identity) { + g_object_unref(d->identity); + } + + d->identity = identity; + + if (d->identity) { + g_object_ref(d->identity); + } +} + +QString Identity::toString() const +{ + Q_ASSERT(d->identity); + return QString::fromUtf8(polkit_identity_to_string(d->identity)); +} + +Identity Identity::fromString(const QString &string) +{ + GError *error = nullptr; + PolkitIdentity *pkIdentity = polkit_identity_from_string(string.toUtf8().data(), &error); + if (error != nullptr) { + qWarning() << QString("Cannot create Identity from string: %1").arg(error->message); + return Identity(); + } + return Identity(pkIdentity); +} + +UnixGroupIdentity Identity::toUnixGroupIdentity() +{ + UnixGroupIdentity *ugid = static_cast< UnixGroupIdentity* >(this); + if (!ugid) { + return UnixGroupIdentity(); + } + + return *ugid; +} + +UnixUserIdentity Identity::toUnixUserIdentity() +{ + UnixUserIdentity *uuid = static_cast< UnixUserIdentity* >(this); + if (!uuid) { + return UnixUserIdentity(); + } + + return *uuid; +} + +UnixUserIdentity::UnixUserIdentity(const QString &name) + : Identity() +{ + GError *error = nullptr; + setIdentity(polkit_unix_user_new_for_name(name.toUtf8().data(), &error)); + if (error != nullptr) { + qWarning() << QString("Cannot create UnixUserIdentity: %1").arg(error->message); + setIdentity(nullptr); + } +} + +UnixUserIdentity::UnixUserIdentity(uid_t uid) + : Identity() +{ + setIdentity(polkit_unix_user_new(uid)); +} + +UnixUserIdentity::UnixUserIdentity(PolkitUnixUser *pkUnixUser) + : Identity((PolkitIdentity *)pkUnixUser) +{ + +} + +UnixUserIdentity::UnixUserIdentity() + : Identity() +{ + +} + +uid_t UnixUserIdentity::uid() const +{ + return polkit_unix_user_get_uid((PolkitUnixUser *) identity()); +} + +void UnixUserIdentity::setUid(uid_t uid) +{ + polkit_unix_user_set_uid((PolkitUnixUser *) identity(), uid); +} + +UnixGroupIdentity::UnixGroupIdentity(const QString &name) + : Identity() +{ + GError *error = nullptr; + setIdentity(polkit_unix_group_new_for_name(name.toUtf8().data(), &error)); + if (error != nullptr) { + qWarning() << QString("Cannot create UnixGroupIdentity: %1").arg(error->message); + setIdentity(nullptr); + } +} + +UnixGroupIdentity::UnixGroupIdentity(gid_t gid) + : Identity() +{ + setIdentity(polkit_unix_group_new(gid)); +} + +UnixGroupIdentity::UnixGroupIdentity(PolkitUnixGroup *pkUnixGroup) + : Identity((PolkitIdentity *) pkUnixGroup) +{ + +} + +UnixGroupIdentity::UnixGroupIdentity() + : Identity() +{ + +} + +gid_t UnixGroupIdentity::gid() const +{ + return polkit_unix_group_get_gid((PolkitUnixGroup *) identity()); +} + +void UnixGroupIdentity::setGid(gid_t gid) +{ + polkit_unix_group_set_gid((PolkitUnixGroup *) identity(), gid); +} + +} diff --git a/local/recipes/libs/polkit-qt6/source/core/polkitqt1-identity.h b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-identity.h new file mode 100644 index 0000000000..57dbdc7ec5 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-identity.h @@ -0,0 +1,198 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Lukas Tinkl + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef POLKITQT1_IDENTITY_H +#define POLKITQT1_IDENTITY_H + +#include "polkitqt1-core-export.h" + +#include + +#include +#include + +typedef struct _PolkitIdentity PolkitIdentity; +typedef struct _PolkitUnixUser PolkitUnixUser; +typedef struct _PolkitUnixGroup PolkitUnixGroup; + +/** + * \namespace PolkitQt1 PolkitQt + * + * \brief Namespace wrapping Polkit-Qt classes + * + * This namespace wraps all Polkit-Qt classes. + */ +namespace PolkitQt1 +{ + +class UnixUserIdentity; +class UnixGroupIdentity; + +/** + * \class Identity polkitqt1-identity.h Identity + * \author Lukas Tinkl + * + * This class encapsulates the PolkitIdentity interface. + * + * \brief Abstract class representing identities + * + * \see UnixGroup + * \see UnixUser + */ +class POLKITQT1_CORE_EXPORT Identity +{ +public: + typedef QList< Identity > List; + + Identity(); + explicit Identity(PolkitIdentity *polkitIdentity); + Identity(const Identity &other); + + ~Identity(); + + Identity &operator=(const Identity &other); + + bool isValid() const; + + /** + * Serialization of object to the string + * + * \return Serialized Identity object + */ + QString toString() const; + + /** + * Creates the Identity object from string representation + * + * \param string string representation of the object + * + * \return Pointer to new Identity instance + */ + static Identity fromString(const QString &string); + + UnixUserIdentity toUnixUserIdentity(); + UnixGroupIdentity toUnixGroupIdentity(); + + /** + * Gets PolkitIdentity object. + * + * \warning It shouldn't be used directly unless you are completely aware of what are you doing + * + * \return Pointer to PolkitIdentity instance + */ + PolkitIdentity *identity() const; +protected: + void setIdentity(PolkitIdentity *identity); + +private: + class Data; + QExplicitlySharedDataPointer< Data > d; +}; + +/** + * \class UnixUserIdentity polkitqt1-identity.h Identity + * + * An object representing a user identity on a UNIX system. + * + * \brief UNIX user identity + * \sa Identity + */ +class POLKITQT1_CORE_EXPORT UnixUserIdentity : public Identity +{ +public: + UnixUserIdentity(); + /** + * Creates UnixUser object by UID of the user + * + * \param uid user id + */ + explicit UnixUserIdentity(uid_t uid); + + /** + * Creates UnixUser object by unix name of the user + * + * \param name Unix name + */ + explicit UnixUserIdentity(const QString &name); + + /** + * Creates UnixUser object from PolkitUnixUser object + * + * \warning Use this only if you are completely aware of what are you doing! + * + * \param pkUnixUser The PolkitUnixUser object + */ + explicit UnixUserIdentity(PolkitUnixUser *pkUnixUser); + + /** + * Gets an user id + * + * \return user id + */ + uid_t uid() const; + + /** + * Sets the id of user + * + * \param uid user id + */ + void setUid(uid_t uid); +}; + +/** + * \class UnixGroupIdentity polkitqt1-identity.h Identity + * + * An object representing a group identity on a UNIX system. + * + * \brief UNIX group identity + * \sa Identity + */ +class POLKITQT1_CORE_EXPORT UnixGroupIdentity : public Identity +{ +public: + UnixGroupIdentity(); + /** + * Creates UnixGroup object by GID of the group + * + * \param gid group id + */ + explicit UnixGroupIdentity(gid_t gid); + + /** + * Creates UnixGroup object by unix name of the group + * + * \param name group name + */ + explicit UnixGroupIdentity(const QString &name); + + /** + * Creates UnixGroup object from PolkitUnixGroup object + * + * \warning Use this only if you are completely aware of what are you doing! + * + * \param pkUnixGroup The PolkitUnixGroup object + */ + explicit UnixGroupIdentity(PolkitUnixGroup *pkUnixGroup); + + /** + * Gets a group id + * + * \return group id + */ + gid_t gid() const; + + /** + * Sets the id of group + * + * \param gid group id + */ + void setGid(gid_t gid); +}; + +} + +#endif // POLKIT_QT_IDENTITY_H diff --git a/local/recipes/libs/polkit-qt6/source/core/polkitqt1-subject.cpp b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-subject.cpp new file mode 100644 index 0000000000..b1796a9abe --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-subject.cpp @@ -0,0 +1,213 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "polkitqt1-subject.h" +#include "polkitqt1-identity.h" +#include "polkitqt1-config.h" + +#include +#include + +namespace PolkitQt1 +{ + +class Q_DECL_HIDDEN Subject::Data : public QSharedData +{ +public: + Data() + : QSharedData() + , subject(nullptr) + {} + Data(const Data& other) = delete; + ~Data() + { + if (subject) { + g_object_unref(subject); + } + } + + PolkitSubject *subject; +}; + +Subject::Subject() + : d(new Data) +{ +} + +Subject::Subject(PolkitSubject *subject) + : d(new Data) +{ + d->subject = subject; + + if (d->subject != nullptr) { + g_object_ref(d->subject); + } +} + +Subject::Subject(const PolkitQt1::Subject& other) + : d(other.d) +{ + +} + +Subject& Subject::operator=(const PolkitQt1::Subject& other) +{ + d = other.d; + return *this; +} + +Subject::~Subject() +{ +} + +bool Subject::isValid() const +{ + return d->subject != nullptr; +} + +PolkitSubject *Subject::subject() const +{ + return d->subject; +} + +void Subject::setSubject(PolkitSubject *subject) +{ + if (d->subject != nullptr) { + g_object_unref(d->subject); + } + d->subject = subject; +} + +QString Subject::toString() const +{ + Q_ASSERT(d->subject); + return QString::fromUtf8(polkit_subject_to_string(d->subject)); +} + +Subject Subject::fromString(const QString &string) +{ + Subject subject; + GError *error = nullptr; + subject.d->subject = polkit_subject_from_string(string.toUtf8().data(), &error); + if (error != nullptr) { + qWarning() << QString("Cannot create Subject from string: %1").arg(error->message); + return {}; + } + return subject; +} + +Subject Subject::fromSubject(PolkitSubject *subject) +{ + return Subject{subject}; +} + +UnixProcessSubject::UnixProcessSubject(qint64 pid) + : Subject() +{ + setSubject(polkit_unix_process_new_for_owner(pid, 0, -1)); +} + +UnixProcessSubject::UnixProcessSubject(qint64 pid, quint64 startTime) + : Subject() +{ + setSubject(polkit_unix_process_new_for_owner(pid, startTime, -1)); +} + +UnixProcessSubject::UnixProcessSubject(PolkitUnixProcess *pkUnixProcess) + : Subject((PolkitSubject *) pkUnixProcess) +{ + +} + +qint64 UnixProcessSubject::pid() const +{ + return polkit_unix_process_get_pid((PolkitUnixProcess *) subject()); +} + +qint64 UnixProcessSubject::startTime() const +{ + return polkit_unix_process_get_start_time((PolkitUnixProcess *) subject()); +} + +qint64 UnixProcessSubject::uid() const +{ + return polkit_unix_process_get_uid((PolkitUnixProcess *) subject()); +} + +void UnixProcessSubject::setPid(qint64 pid) +{ + polkit_unix_process_set_pid((PolkitUnixProcess *) subject(), pid); +} + +// ----- SystemBusName +SystemBusNameSubject::SystemBusNameSubject(const QString &name) + : Subject() +{ + setSubject(polkit_system_bus_name_new(name.toUtf8().data())); +} + +SystemBusNameSubject::SystemBusNameSubject(PolkitSystemBusName *pkSystemBusName) + : Subject((PolkitSubject *) pkSystemBusName) +{ + +} + +QString SystemBusNameSubject::name() const +{ + return QString::fromUtf8(polkit_system_bus_name_get_name((PolkitSystemBusName *) subject())); +} + +void SystemBusNameSubject::setName(const QString &name) +{ + polkit_system_bus_name_set_name((PolkitSystemBusName *) subject(), name.toUtf8().data()); +} + +UnixUserIdentity SystemBusNameSubject::user() +{ +#if HAVE_POLKIT_SYSTEM_BUS_NAME_GET_USER_SYNC + return UnixUserIdentity(polkit_system_bus_name_get_user_sync((PolkitSystemBusName *) subject(), nullptr, nullptr)); +#else + qWarning("Polkit is too old, returning invalid user from SystemBusNameSubject::user()!"); + return UnixUserIdentity(); +#endif +} + +// ----- SystemSession +UnixSessionSubject::UnixSessionSubject(const QString &sessionId) + : Subject() +{ + setSubject(polkit_unix_session_new(sessionId.toUtf8().data())); +} + +UnixSessionSubject::UnixSessionSubject(qint64 pid) + : Subject() +{ + GError *error = nullptr; + setSubject(polkit_unix_session_new_for_process_sync(pid, nullptr, &error)); + if (error != nullptr) { + qWarning() << QString("Cannot create unix session: %1").arg(error->message); + setSubject(nullptr); + } +} + +UnixSessionSubject::UnixSessionSubject(PolkitSystemBusName *pkUnixSession) + : Subject((PolkitSubject *) pkUnixSession) +{ + +} + +QString UnixSessionSubject::sessionId() const +{ + return QString::fromUtf8(polkit_unix_session_get_session_id((PolkitUnixSession *) subject())); +} + +void UnixSessionSubject::setSessionId(const QString &sessionId) +{ + polkit_unix_session_set_session_id((PolkitUnixSession *) subject(), sessionId.toUtf8().data()); +} + +} diff --git a/local/recipes/libs/polkit-qt6/source/core/polkitqt1-subject.h b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-subject.h new file mode 100644 index 0000000000..ef965f54de --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-subject.h @@ -0,0 +1,276 @@ +/* + This file is part of the PolKit1-qt project + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef POLKITQT1_SUBJECT_H +#define POLKITQT1_SUBJECT_H + +#include "polkitqt1-core-export.h" + +#include +#include + +typedef struct _PolkitSubject PolkitSubject; +typedef struct _PolkitUnixProcess PolkitUnixProcess; +typedef struct _PolkitSystemBusName PolkitSystemBusName; + +/** + * \namespace PolkitQt1 PolkitQt + * + * \brief Namespace wrapping PolicyKit-Qt classes + * + * This namespace wraps all PolicyKit-Qt classes. + */ +namespace PolkitQt1 +{ + +class UnixUserIdentity; + +/** + * \class Subject polkitqt1-subject.h Subject + * \author Jaroslav Reznik + * + * \brief This class represents PolicyKit subjects + * + * This class encapsulates the PolkitSubject interface. + * + * \see UnixProcess + * \see SystemBusName + * \see UnixSession + */ +class POLKITQT1_CORE_EXPORT Subject +{ +public: + Subject(); + Subject(const Subject &other); + ~Subject(); + + Subject &operator=(const Subject &other); + + bool isValid() const; + + /** + * Serialization of object to the string + * + * \return Serialized Subject object + */ + QString toString() const; + + /** + * Creates the Subject object from string reprezentation + * + * \param string string reprezentation of the object + * + * \return Pointer to new Subject instance + */ + static Subject fromString(const QString &string); + + /** + * Creates the Subject object + * + * \param subject string reprezentation of the object + * + * \return A new Subject instance + */ + static Subject fromSubject(PolkitSubject *subject); + + /** + * Gets PolkitSubject object. + * + * \warning It shouldn't be used directly unless you are completely aware of what are you doing + * + * \return Pointer to PolkitSubject instance + */ + PolkitSubject *subject() const; + +protected: + explicit Subject(PolkitSubject *subject); + + void setSubject(PolkitSubject *subject); + +private: + class Data; + QExplicitlySharedDataPointer< Data > d; +}; + +/** + * \class UnixProcessSubject polkitqt1-subject.h Subject + * \author Jaroslav Reznik + * + * \brief A class for representing a UNIX process. + * + * To uniquely identify processes, both the process + * id and the start time of the process (a monotonic + * increasing value representing the time since the + * kernel was started) is used. + * + * \sa Subject + */ +class POLKITQT1_CORE_EXPORT UnixProcessSubject : public Subject +{ +public: + /** + * Subject constructor, takes one parameter - PID. The start time + * of process will be looked automatically. + * + * \param pid An Unix process PID. + */ + explicit UnixProcessSubject(qint64 pid); + + /** + * Subject constructor, takes two parameters - PID and start time. + * + * \param pid An Unix process PID. + * \param startTime An Unix process start time. + */ + UnixProcessSubject(qint64 pid, quint64 startTime); + + /** + * Subject constructor, it creates UnixProcess object from PolkitUnixProcess object + * + * \warning Use this only if you are completely aware of what are you doing! + * + * \param process PolkitUnixProcess object + */ + explicit UnixProcessSubject(PolkitUnixProcess *process); + + /** + * Returns Unix process PID. + * + * \return A PID of associated Unix process. + */ + qint64 pid() const; + + /** + * Returns Unix process start time. + * + * \return A start time of associated Unix process. + */ + qint64 startTime() const; + + /** + * Returns Unix process UID. + * + * \return A UID of associated Unix process. + */ + qint64 uid() const; + + /** + * Sets Unix process PID. + * + * \param pid An Unix process PID. + */ + void setPid(qint64 pid); +}; + +/** + * \class SystemBusNameSubject polkitqt1-subject.h Subject + * \author Jaroslav Reznik + * + * \brief A class for representing a process owning a unique name on the system bus. + * + * \sa Subject + */ +class POLKITQT1_CORE_EXPORT SystemBusNameSubject : public Subject +{ +public: + /** + * Subject constructor, takes one parameter - system bus name. + * + * \param name A unique system bus name. + */ + explicit SystemBusNameSubject(const QString &name); + + /** + * Subject constructor, it creates SystemBusName object from PolkitSystemBusName object + * + * \warning Use this only if you are completely aware of what are you doing! + * + * \param pkSystemBusName PolkitSystemBusName object + */ + explicit SystemBusNameSubject(PolkitSystemBusName *pkSystemBusName); + + /** + * Returns system bus name. + * + * \return A unique system bus name. + */ + QString name() const; + + /** + * Sets system bus name. + * + * \param name System bus name. + */ + void setName(const QString &name); + + /** + * Returns the UnixUserIdentity for this subject. + * + * \note This can be an invalid UnixUserIdentity so be sure to check before using it + * + * \since 0.113 + **/ + UnixUserIdentity user(); +}; + +/** + * \class UnixSessionSubject polkitqt1-subject.h Subject + * \author Jaroslav Reznik + * + * \brief A class for representing unix session. + * + * The session id is an opaque string obtained from + * ConsoleKit. + * + * \sa Subject + */ +class POLKITQT1_CORE_EXPORT UnixSessionSubject : public Subject +{ +public: + /** + * Subject constructor, takes one parameter - session id. + * + * \param sessionId The session id. + */ + explicit UnixSessionSubject(const QString &sessionId); + + /** + * Subject constructor, takes one parameter - pid of process. + * + * Synchronous! + * + * \param pid The session's process pid. + */ + explicit UnixSessionSubject(qint64 pid); + + /** + * Subject constructor, it creates UnixSession object from PolkitUnixSession object + * + * \warning Use this only if you are completely aware of what are you doing! + * + * \param pkUnixSession PolkitUnixSession object + */ + explicit UnixSessionSubject(PolkitSystemBusName *pkUnixSession); + + /** + * Returns session id. + * + * \return A session id. + */ + QString sessionId() const; + + /** + * Sets session id. + * + * \param sessionId A session id. + */ + void setSessionId(const QString &sessionId); +}; + +} + +#endif diff --git a/local/recipes/libs/polkit-qt6/source/core/polkitqt1-temporaryauthorization.cpp b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-temporaryauthorization.cpp new file mode 100644 index 0000000000..ffa6a5e130 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-temporaryauthorization.cpp @@ -0,0 +1,103 @@ +/* + This file is part of the PolKit1-qt project + SPDX-FileCopyrightText: 2009 Radek Novacek + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "polkitqt1-temporaryauthorization.h" +#include "polkitqt1-authority.h" + +#include + +namespace PolkitQt1 +{ + +class Q_DECL_HIDDEN TemporaryAuthorization::Data : public QSharedData +{ +public: + Data() {} + Data(const Data& other) + : QSharedData(other) + , id(other.id) + , actionId(other.actionId) + , subject(other.subject) + , timeObtained(other.timeObtained) + , timeExpires(other.timeExpires) + { + } + ~Data() {} + + QString id; + QString actionId; + Subject subject; + QDateTime timeObtained; + QDateTime timeExpires; +}; + +TemporaryAuthorization::TemporaryAuthorization(PolkitTemporaryAuthorization *pkTemporaryAuthorization) + : d(new Data) +{ + d->id = QString::fromUtf8(polkit_temporary_authorization_get_id(pkTemporaryAuthorization)); + d->actionId = QString::fromUtf8(polkit_temporary_authorization_get_action_id(pkTemporaryAuthorization)); + d->subject = Subject::fromSubject(polkit_temporary_authorization_get_subject(pkTemporaryAuthorization)); + d->timeObtained = QDateTime::fromSecsSinceEpoch(polkit_temporary_authorization_get_time_obtained(pkTemporaryAuthorization)); + d->timeExpires = QDateTime::fromSecsSinceEpoch(polkit_temporary_authorization_get_time_expires(pkTemporaryAuthorization)); + g_object_unref(pkTemporaryAuthorization); +} + +TemporaryAuthorization::TemporaryAuthorization(const PolkitQt1::TemporaryAuthorization& other) + : d(other.d) +{ + +} + +TemporaryAuthorization::TemporaryAuthorization() + : d(new Data) +{ + +} + +TemporaryAuthorization& TemporaryAuthorization::operator=(const PolkitQt1::TemporaryAuthorization& other) +{ + d = other.d; + return *this; +} + +TemporaryAuthorization::~TemporaryAuthorization() +{ +} + +QString TemporaryAuthorization::id() const +{ + return d->id; +} + +QString TemporaryAuthorization::actionId() const +{ + return d->actionId; +} + +Subject TemporaryAuthorization::subject() const +{ + //qFatal(polkit_subject_to_string(polkit_temporary_authorization_get_subject(d->temporaryAuthorization))); + return d->subject;//Subject::fromString(polkit_subject_to_string(d->subject)); +} + +QDateTime TemporaryAuthorization::obtainedAt() const +{ + return d->timeObtained; +} + +QDateTime TemporaryAuthorization::expirationTime() const +{ + return d->timeExpires; +} + +bool TemporaryAuthorization::revoke() +{ + Authority::instance()->revokeTemporaryAuthorization(id()); + return true; +} + +} diff --git a/local/recipes/libs/polkit-qt6/source/core/polkitqt1-temporaryauthorization.h b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-temporaryauthorization.h new file mode 100644 index 0000000000..b378991523 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/core/polkitqt1-temporaryauthorization.h @@ -0,0 +1,111 @@ +/* + This file is part of the PolKit1-qt project + SPDX-FileCopyrightText: 2009 Radek Novacek + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef POLKITQT1_TEMPORARYAUTHORIZATION_H +#define POLKITQT1_TEMPORARYAUTHORIZATION_H + +#include "polkitqt1-subject.h" + +#include +#include +#include +#include + +typedef struct _PolkitTemporaryAuthorization PolkitTemporaryAuthorization; + +/** + * \namespace PolkitQt1 PolkitQt + * + * \brief Namespace wrapping PolicyKit-Qt classes + * + * This namespace wraps all PolicyKit-Qt classes. + */ +namespace PolkitQt1 +{ + +/** + * \class TemporaryAuthorization polkitqt1-temporaryauthorization.h TemporaryAuthorization + * \author Radek Novacek + * + * \brief This class represents PolicyKit temporary authorization + * + * This class encapsulates the PolkitTemporaryAuthorization interface. + */ +class POLKITQT1_CORE_EXPORT TemporaryAuthorization +{ +public: + typedef QList< TemporaryAuthorization > List; + TemporaryAuthorization(); + /** + * Creates TemporaryAuthorization object from PolkitTemporaryAuthorization + * + * \warning It shouldn't be used directly unless you are completely aware of what are you doing + * + * \param pkTemporaryAuthorization PolkitTemporaryAuthorization object + * \param parent + */ + explicit TemporaryAuthorization(PolkitTemporaryAuthorization *pkTemporaryAuthorization); + TemporaryAuthorization(const TemporaryAuthorization &other); + + ~TemporaryAuthorization(); + + TemporaryAuthorization &operator=(const TemporaryAuthorization &other); + + /** + * \brief Gets the identifier for the authorization. + * + * This identifier can be user by the revokeTemporaryAuthorization function + * + * \return Unique identifier for the authorization + */ + QString id() const; + + /** + * \brief Gets the identifier of the action that authorization is for + * + * \return String that identifies the action + */ + QString actionId() const; + + /** + * \brief Gets the subject that authorization is for + * + * \return A Subject. + */ + Subject subject() const; + + /** + * \brief Gets the time when authorization was obtained + * + * \return Time of obtaining the authorization + */ + QDateTime obtainedAt() const; + + /** + * \brief Gets the time when authorizaton will expire + * + * \return Time of expiration + */ + QDateTime expirationTime() const; + + /** + * \brief Revoke temporary authorization + * + * \return \c true Authorization has been revoked + * \c false Revoking authorization failed + */ + bool revoke(); + +private: + class Data; + QSharedDataPointer< Data > d; +}; +} + +Q_DECLARE_METATYPE(PolkitQt1::TemporaryAuthorization::List) + +#endif // TEMPORARYAUTHORIZATION_H diff --git a/local/recipes/libs/polkit-qt6/source/examples/CMakeLists.txt b/local/recipes/libs/polkit-qt6/source/examples/CMakeLists.txt new file mode 100644 index 0000000000..f128285258 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/CMakeLists.txt @@ -0,0 +1,63 @@ + +install(FILES org.qt.policykit.examples.policy DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/polkit-1/actions/) + +add_executable(${POLKITQT-1_EXAMPLE}) + +target_sources(${POLKITQT-1_EXAMPLE} PRIVATE + main.cpp + PkExample.cpp + + icons/icons.qrc +) + +target_link_libraries(${POLKITQT-1_EXAMPLE} + Qt${QT_MAJOR_VERSION}::Core + Qt${QT_MAJOR_VERSION}::DBus + Qt${QT_MAJOR_VERSION}::Widgets + ${POLKITQT-1_GUI_PCNAME} + ${POLKITQT-1_CORE_PCNAME} +) + +#--------Helper Application + +# This macro is defined in FindPolkitQt.cmake +macro(dbus_add_activation_system_service _sources) + foreach (_i ${_sources}) + get_filename_component(_service_file ${_i} ABSOLUTE) + string(REGEX REPLACE "\\.service.*$" ".service" _output_file ${_i}) + set(_target ${CMAKE_CURRENT_BINARY_DIR}/${_output_file}) + configure_file(${_service_file} ${_target}) + install(FILES ${_target} DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/dbus-1/system-services ) + #install(FILES ${_target} DESTINATION ${_install_dir}) + endforeach (_i ${ARGN}) +endmacro(dbus_add_activation_system_service _sources) + +add_executable(${POLKITQT-1_EXAMPLE_HELPER}) + +qt_add_dbus_adaptor(polkit_example_helper_dbus_SRCS + org.qt.policykit.examples.xml + PkExampleHelper.h + PkExampleHelper +) + +target_sources(${POLKITQT-1_EXAMPLE_HELPER} PRIVATE + PkExampleHelper.cpp + mainHelper.cpp + ${polkit_example_helper_dbus_SRCS} +) + +# see our helper is pretty small :D +target_link_libraries(${POLKITQT-1_EXAMPLE_HELPER} + Qt${QT_MAJOR_VERSION}::Core + Qt${QT_MAJOR_VERSION}::Xml + Qt${QT_MAJOR_VERSION}::DBus + ${POLKITQT-1_GUI_PCNAME} +) + +install(TARGETS ${POLKITQT-1_EXAMPLE_HELPER} RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}) + +dbus_add_activation_system_service(org.qt.policykit.examples.service.in) + +install(FILES org.qt.policykit.examples.conf DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/dbus-1/system.d) + +add_subdirectory(agent) diff --git a/local/recipes/libs/polkit-qt6/source/examples/PkExample.cpp b/local/recipes/libs/polkit-qt6/source/examples/PkExample.cpp new file mode 100644 index 0000000000..f0fe389eb5 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/PkExample.cpp @@ -0,0 +1,227 @@ +// This is an example not a library +/* + SPDX-FileCopyrightText: 2009 Radek Novacek + SPDX-FileCopyrightText: 2008 Daniel Nicoletti + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "PkExample.h" + +#include +#include +#include +#include + +#include +#include + +using namespace PolkitQt1; +using namespace PolkitQt1::Gui; + +PkExample::PkExample(QMainWindow *parent) + : QMainWindow(parent) +{ + setupUi(this); + + ActionButton *bt; + + // Here we create an ActionButton that is a subclass of Action + // always pass a QAbstractButton pointer and action id + // You can change the action id later if you want + bt = new ActionButton(kickPB, "org.qt.policykit.examples.kick", this); + // Here we are setting the text and icon to all four states + // an action might have + bt->setText("Kick!"); + bt->setIcon(QPixmap(":/Icons/custom-no.png")); + // By using set{Yes|No|Auth}Enabled you can set the states + // when the button is enabled + bt->setEnabled(true, Action::No); + // As ActionButton is also an Action we cast it to add to menu + menuActions->addAction(qobject_cast(bt)); + toolBar->addAction(qobject_cast(bt)); + // this signal is emitted when the user click on the action, + // it will only happen if it was inserted in a QMenu or a QToolBar + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + // This signal was propagated from the QAbstractButton just for + // convenience in this case we don't have any benefit but the code + // look cleaner + connect(bt, SIGNAL(clicked(QAbstractButton*,bool)), bt, SLOT(activate())); + // this is the Action activated signal, it is always emitted whenever + // someone click and get authorized to do the action + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + bt = new ActionButton(cryPB, "org.qt.policykit.examples.cry", this); + bt->setText("Cry!"); + bt->setIcon(QPixmap(":/Icons/custom-yes.png")); + menuActions->addAction(qobject_cast(bt)); + toolBar->addAction(qobject_cast(bt)); + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + connect(bt, SIGNAL(clicked(QAbstractButton*,bool)), bt, SLOT(activate())); + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + bt = new ActionButton(bleedPB, "org.qt.policykit.examples.bleed", this); + bt->setText("Bleed!"); + bt->setIcon(QPixmap(":/Icons/action-locked-default.png")); + menuActions->addAction(qobject_cast(bt)); + toolBar->addAction(qobject_cast(bt)); + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + connect(bt, SIGNAL(clicked(QAbstractButton*,bool)), bt, SLOT(activate())); + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + // This action is more customized + bt = new ActionButton(playPB, "org.qt.policykit.examples.play", this); + bt->setText("Play!"); + bt->setVisible(true, Action::No | Action::Auth | Action::Yes); + bt->setEnabled(true, Action::No | Action::Auth | Action::Yes); + // here we set the behavior of PolKitResul = No + bt->setText("Can't play!", Action::No); + bt->setIcon(QPixmap(":/Icons/custom-no.png"), Action::No); + bt->setToolTip("If your admin wasn't annoying, you could do this", Action::No); + // here we set the behavior of PolKitResul = Auth + bt->setText("Play?", Action::Auth); + bt->setIcon(QPixmap(":/Icons/action-locked-default.png"), Action::Auth); + bt->setToolTip("Only card carrying tweakers can do this!", Action::Auth); + // here we set the behavior of PolKitResul = Yes + bt->setText("Play!", Action::Yes); + bt->setIcon(QPixmap(":/Icons/custom-yes.png"), Action::Yes); + bt->setToolTip("Go ahead, play!", Action::Yes); + + menuActions->addAction(qobject_cast(bt)); + toolBar->addAction(qobject_cast(bt)); + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + connect(bt, SIGNAL(clicked(QAbstractButton*,bool)), bt, SLOT(activate())); + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + bt = new ActionButton(deletePB, "org.qt.policykit.examples.delete", this); + bt->setText("Delete!"); + bt->setIcon(QPixmap(":/Icons/custom-no.png"), Action::No); + bt->setIcon(QPixmap(":/Icons/action-locked-default.png"), Action::Auth); + bt->setIcon(QPixmap(":/Icons/custom-yes.png"), Action::Yes); + menuActions->addAction(qobject_cast(bt)); + toolBar->addAction(qobject_cast(bt)); + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + connect(bt, SIGNAL(clicked(QAbstractButton*,bool)), bt, SLOT(activate())); + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + bt = new ActionButton(listenPB, "org.qt.policykit.examples.listen", this); + bt->setText("Listen!"); + bt->setIcon(QPixmap(":/Icons/custom-no.png"), Action::No); + bt->setIcon(QPixmap(":/Icons/action-locked-default.png"), Action::Auth); + bt->setIcon(QPixmap(":/Icons/custom-yes.png"), Action::Yes); + menuActions->addAction(qobject_cast(bt)); + toolBar->addAction(qobject_cast(bt)); + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + connect(bt, SIGNAL(clicked(QAbstractButton*,bool)), bt, SLOT(activate())); + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + bt = new ActionButton(setPB, "org.qt.policykit.examples.set", this); + bt->setText("Set!"); + bt->setIcon(QPixmap(":/Icons/custom-no.png"), Action::No); + bt->setIcon(QPixmap(":/Icons/action-locked-default.png"), Action::Auth); + bt->setIcon(QPixmap(":/Icons/custom-yes.png"), Action::Yes); + menuActions->addAction(qobject_cast(bt)); + toolBar->addAction(qobject_cast(bt)); + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + connect(bt, SIGNAL(clicked(QAbstractButton*,bool)), bt, SLOT(activate())); + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + bt = new ActionButton(shoutPB, "org.qt.policykit.examples.shout", this); + bt->setIcon(QPixmap(":/Icons/custom-no.png"), Action::No); + bt->setIcon(QPixmap(":/Icons/action-locked-default.png"), Action::Auth); + bt->setIcon(QPixmap(":/Icons/custom-yes.png"), Action::Yes); + bt->setText("Can't shout!", Action::No); + bt->setText("Shout?", Action::Auth); + bt->setText("Shout!", Action::Yes); + menuActions->addAction(qobject_cast(bt)); + toolBar->addAction(qobject_cast(bt)); + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + connect(bt, SIGNAL(clicked(QAbstractButton*,bool)), bt, SLOT(activate())); + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + // test configChanged +} + +PkExample::~PkExample() +{ +} + +void PkExample::activateAction() +{ + // Here we cast the sender() to an Action and call activate() + // on it. + // Be careful in doing the same for ActionButton won't work as expected + // as action->activate() is calling Action::activate() and + // not ActionButton::activate which are different. + // You can cast then to ActionButton but be careful + // an Action casted to ActionButton may crash you app + Action *action = qobject_cast(sender()); + // calling activate with winId() makes the auth dialog + // be correct parented with your application. + action->activate(); +} + +void PkExample::actionActivated() +{ + // This slot is called whenever an action is allowed + // here you will do your dirt job by calling a helper application + // that might erase your hardrive ;) + Action *action = qobject_cast(sender()); + + // this is our Special Action that after allowed will call the helper + if (action->is("org.qt.policykit.examples.set")) { + qDebug() << "toggled for: org.qt.policykit.examples.set"; + + QDBusMessage message; + message = QDBusMessage::createMethodCall("org.qt.policykit.examples", + "/", + "org.qt.policykit.examples", + QLatin1String("set")); + QList argumentList; + argumentList << QVariant::fromValue(setCB->currentText()); + message.setArguments(argumentList); + // notice the systemBus here.. + QDBusMessage reply = QDBusConnection::systemBus().call(message); + if (reply.type() == QDBusMessage::ReplyMessage + && reply.arguments().size() == 1) { + // the reply can be anything, here we receive a bool + QListWidgetItem *item; + if (reply.arguments().first().toBool()) + item = new QListWidgetItem(QPixmap(":/Icons/custom-yes.png"), + QString("Implicit authorization for shout has been set to %0") + .arg(setCB->currentText())); + else + item = new QListWidgetItem(QPixmap(":/Icons/custom-no.png"), + QString("Can't change the implicit authorization. Denied.")); + actionList->addItem(item); + qDebug() << reply.arguments().first().toString(); + } else if (reply.type() == QDBusMessage::MethodCallMessage) { + qWarning() << "Message did not receive a reply (timeout by message bus)"; + } + return; + } + + // As debug message says we are pretending to be the mechanism for the + // following action, here you will actually call your DBus helper that + // will run as root (setuid is not needed, see DBus docs). + // In the helper application you will issue checkAuthorizationSync, + // passing the action id and the caller pid (which DBus will tell you). + qDebug() << "pretending to be the mechanism for action:" << action->actionId(); + + Authority::Result result; + UnixProcessSubject subject(static_cast(QCoreApplication::applicationPid())); + + result = Authority::instance()->checkAuthorizationSync(action->actionId(), subject, + Authority::AllowUserInteraction); + if (result == Authority::Yes) { + // in the helper you will do the action + qDebug() << "caller is authorized to do:" << action->actionId(); + QListWidgetItem *item = new QListWidgetItem(QPixmap(":/Icons/custom-yes.png"), action->actionId()); + actionList->addItem(item); + } else { + // OR return false to notify the caller that the action is not authorized. + qDebug() << "caller is NOT authorized to do:" << action->actionId(); + QListWidgetItem *item = new QListWidgetItem(QIcon(":/Icons/custom-no.png"), action->actionId()); + actionList->addItem(item); + } +} diff --git a/local/recipes/libs/polkit-qt6/source/examples/PkExample.h b/local/recipes/libs/polkit-qt6/source/examples/PkExample.h new file mode 100644 index 0000000000..e69b410c7f --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/PkExample.h @@ -0,0 +1,28 @@ +// This is an example not a library +/* + SPDX-FileCopyrightText: 2008 Daniel Nicoletti + SPDX-FileCopyrightText: 2009 Radek Novacek + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#ifndef PKEXAMPLE_H +#define PKEXAMPLE_H + +#include "ui_PkExample.h" + +class PkExample : public QMainWindow, Ui::PkExample +{ + Q_OBJECT + +public: + PkExample(QMainWindow *parent = nullptr); + ~PkExample() override; + +private Q_SLOTS: + void activateAction(); + void actionActivated(); +}; + + +#endif diff --git a/local/recipes/libs/polkit-qt6/source/examples/PkExample.ui b/local/recipes/libs/polkit-qt6/source/examples/PkExample.ui new file mode 100644 index 0000000000..8997e506a9 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/PkExample.ui @@ -0,0 +1,234 @@ + + + PkExample + + + + 0 + 0 + 800 + 600 + + + + PolicyKit-qt example + + + + + + + + + Making the helper <b>Kick</b> is not allowed. Action cannot be triggered. + + + true + + + + + + + Kick! + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Making the helper <span style=" font-weight:600;">Cry</span> is always allowed. Action can be triggered without authentication.</p></body></html> + + + true + + + + + + + Cry! + + + + + + + Making the helper <b>Bleed</b> requires the user to authenticate. This is a one-shot authorization. + + + true + + + + + + + Bleed! + + + + + + + Making the helper <b>Play</b> requires a system administrator to authenticate. This is a one-shot authorization. + + + true + + + + + + + Play! + + + + + + + Making the helper <b>Listen</b> requires the user to authenticate. The authorization will be kept for a brief period. + + + true + + + + + + + Listen! + + + + + + + Making the helper <b>Delete</b> requires a system administrator to authenticate. The authorization will be kept for a brief period. + + + true + + + + + + + Delete! + + + + + + + <b>Set</b> is special action. It sets the permissions for the <b>Shout</b> action by actually using the helper application to change the implicit authorization. + + + true + + + + + + + + no + + + + + yes + + + + + auth_self + + + + + auth_admin + + + + + auth_self_keep + + + + + auth_admin_keep + + + + + + + + Set! + + + + + + + The implicit authorization for the <b>Shout</b> action is set by the <b>Set</b> action. You can watch how different options can change behaviour of this action. + + + true + + + + + + + Shout! + + + + + + + + + + + + + + 0 + 0 + 800 + 22 + + + + + Actions + + + + + + + toolBar + + + Qt::ToolButtonTextUnderIcon + + + TopToolBarArea + + + false + + + + + + diff --git a/local/recipes/libs/polkit-qt6/source/examples/PkExampleHelper.cpp b/local/recipes/libs/polkit-qt6/source/examples/PkExampleHelper.cpp new file mode 100644 index 0000000000..a4827ca66f --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/PkExampleHelper.cpp @@ -0,0 +1,97 @@ +// This is an example not a library +/* + SPDX-FileCopyrightText: 2008 Daniel Nicoletti + SPDX-FileCopyrightText: 2009 Radek Novacek + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "PkExampleHelper.h" +#include "examplesadaptor.h" + +#include + +#include +#include +#include +#include + +#define MINUTE 60000 + +using namespace PolkitQt1; + +PkExampleHelper::PkExampleHelper(int &argc, char **argv) + : QCoreApplication(argc, argv) +{ + qDebug() << "Creating Helper"; + (void) new ExamplesAdaptor(this); + // Register the DBus service + if (!QDBusConnection::systemBus().registerService("org.qt.policykit.examples")) { + qDebug() << QDBusConnection::systemBus().lastError().message();; + QTimer::singleShot(0, this, SLOT(quit())); + return; + } + + if (!QDBusConnection::systemBus().registerObject("/", this)) { + qDebug() << "unable to register service interface to dbus"; + QTimer::singleShot(0, this, SLOT(quit())); + return; + } + // Normally you will set a timeout so your application can + // free some resources of the poor client machine ;) + QTimer::singleShot(MINUTE, this, SLOT(quit())); +} + +PkExampleHelper::~PkExampleHelper() +{ + qDebug() << "Destroying Helper"; +} + +bool PkExampleHelper::set(const QString &action) +{ + qDebug() << "PkExampleHelper::set" << action; + // message().service() is the service name of the caller + // We can check if the caller is authorized to the following action + Authority::Result result; + SystemBusNameSubject subject(message().service()); + + result = Authority::instance()->checkAuthorizationSync("org.qt.policykit.examples.set", + subject , Authority::AllowUserInteraction); + if (result == Authority::Yes) { + qDebug() << message().service() << QString("Implicit authorization set to") << action; + // Caller is authorized so we can perform the action + return setValue(action); + } else { + qDebug() << message().service() << QString("Can't set the implicit authorization"); + // Caller is not authorized so the action can't be performed + return false; + } +} + +bool PkExampleHelper::setValue(const QString &action) +{ + // This action must be authorized first. It will set the implicit + // authorization for the Shout action by editing the .policy file + QDomDocument doc = QDomDocument("policy"); + QFile file("/usr/share/polkit-1/actions/org.qt.policykit.examples.policy"); + if (!file.open(QIODevice::ReadOnly)) + return false; + doc.setContent(&file); + file.close(); + QDomElement el = doc.firstChildElement("policyconfig"). + firstChildElement("action"); + while (!el.isNull() && el.attribute("id", QString()) != "org.qt.policykit.examples.shout") { + el = el.nextSiblingElement("action"); + } + el = el.firstChildElement("defaults"); + el = el.firstChildElement("allow_active"); + if (el.isNull()) + return false; + el.firstChild().toText().setData(action); + if (!file.open(QIODevice::WriteOnly)) + return false; + QTextStream stream(&file); + doc.save(stream, 2); + file.close(); + return true; +} diff --git a/local/recipes/libs/polkit-qt6/source/examples/PkExampleHelper.h b/local/recipes/libs/polkit-qt6/source/examples/PkExampleHelper.h new file mode 100644 index 0000000000..9133c6b105 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/PkExampleHelper.h @@ -0,0 +1,29 @@ +// This is an example not a library +/* + SPDX-FileCopyrightText: 2008 Daniel Nicoletti + SPDX-FileCopyrightText: 2009 Radek Novacek + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#ifndef PKEXAMPLE_HELPER_H +#define PKEXAMPLE_HELPER_H + +#include +#include + +class PkExampleHelper : public QCoreApplication, protected QDBusContext +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.qt.policykit.examples") +public: + PkExampleHelper(int &argc, char **argv); + ~PkExampleHelper() override; + +public Q_SLOTS: + bool set(const QString &action); + bool setValue(const QString &action); +}; + + +#endif diff --git a/local/recipes/libs/polkit-qt6/source/examples/agent/CMakeLists.txt b/local/recipes/libs/polkit-qt6/source/examples/agent/CMakeLists.txt new file mode 100644 index 0000000000..130ac4ecea --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/agent/CMakeLists.txt @@ -0,0 +1,16 @@ +add_executable(${POLKITQT-1_AGENT_EXAMPLE}) + +target_sources(${POLKITQT-1_AGENT_EXAMPLE} PRIVATE + main.cpp + pkagentexample.cpp + klistener.cpp +) + +target_link_libraries(${POLKITQT-1_AGENT_EXAMPLE} + Qt${QT_MAJOR_VERSION}::Core + Qt${QT_MAJOR_VERSION}::Widgets + ${POLKITQT-1_AGENT_PCNAME} + ${POLKITQT-1_CORE_PCNAME} + PkgConfig::POLKIT_AGENT + PkgConfig::GOBJECT +) diff --git a/local/recipes/libs/polkit-qt6/source/examples/agent/klistener.cpp b/local/recipes/libs/polkit-qt6/source/examples/agent/klistener.cpp new file mode 100644 index 0000000000..0c4d0aec05 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/agent/klistener.cpp @@ -0,0 +1,88 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include +#include + +#include "klistener.h" +#include + +using namespace PolkitQt1::Agent; + +KListener::KListener(QObject *parent) + : Listener(parent) +{ + qDebug() << "Registering KDE listener"; +} + +// README: this is just testing code... + +void KListener::initiateAuthentication(const QString &actionId, + const QString &message, + const QString &iconName, + const PolkitQt1::Details &details, + const QString &cookie, + const PolkitQt1::Identity::List &identities, + AsyncResult *result) +{ + qDebug() << "initiateAuthentication for " << actionId << " with message " << message; + qDebug() << "iconName " << iconName; + qDebug() << details.keys(); + qDebug() << "cookie" << cookie; + + Q_FOREACH (const PolkitQt1::Identity &identity, identities) { + qDebug() << identity.toString(); + Session *session; + session = new Session(identity, cookie, result); + connect(session, SIGNAL(request(QString,bool)), this, SLOT(request(QString,bool))); + connect(session, SIGNAL(completed(bool)), this, SLOT(completed(bool))); + connect(session, SIGNAL(showError(QString)), this, SLOT(showError(QString))); + connect(session, SIGNAL(showInfo(QString)), this, SLOT(showInfo(QString))); + session->initiate(); + } +} + +bool KListener::initiateAuthenticationFinish() +{ + qDebug() << "initiateAuthenticationFinish()"; + return true; +} + +void KListener::cancelAuthentication() +{ + qDebug() << "Cancelling authentication"; +} + +void KListener::request(const QString &request, bool echo) +{ + qDebug() << "Request: " << request; + + Session *session = (Session *)sender(); + + session->setResponse(""); +} + +void KListener::completed(bool gainedAuthorization) +{ + qDebug() << "Completed: " << gainedAuthorization; + Session *session = (Session *)sender(); + + session->result()->setCompleted(); + // This slot is invoked from the Session::completed signal (emitted in Session::Private::completed). + // Use deleteLater() to defer Session destruction; synchronous delete inside the signal callback would be unsafe. + session->deleteLater(); +} + +void KListener::showError(const QString &text) +{ + qDebug() << "Error: " << text; +} + +void KListener::showInfo(const QString &text) +{ + qDebug() << "Info: " << text; +} diff --git a/local/recipes/libs/polkit-qt6/source/examples/agent/klistener.h b/local/recipes/libs/polkit-qt6/source/examples/agent/klistener.h new file mode 100644 index 0000000000..ef01642e76 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/agent/klistener.h @@ -0,0 +1,43 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef POLKIT_QT_AGENT_KDE_LISTENER_H +#define POLKIT_QT_AGENT_KDE_LISTENER_H + +#include +#include + +#include +#include +#include +#include + +class KListener : public PolkitQt1::Agent::Listener +{ + Q_OBJECT + Q_DISABLE_COPY(KListener) +public: + KListener(QObject *parent = nullptr); + ~KListener() override {}; +public Q_SLOTS: + void initiateAuthentication(const QString &actionId, + const QString &message, + const QString &iconName, + const PolkitQt1::Details &details, + const QString &cookie, + const PolkitQt1::Identity::List &identities, + PolkitQt1::Agent::AsyncResult *result) override; + bool initiateAuthenticationFinish() override; + void cancelAuthentication() override; + + void request(const QString &request, bool echo); + void completed(bool gainedAuthorization); + void showError(const QString &text); + void showInfo(const QString &text); +}; + +#endif diff --git a/local/recipes/libs/polkit-qt6/source/examples/agent/main.cpp b/local/recipes/libs/polkit-qt6/source/examples/agent/main.cpp new file mode 100644 index 0000000000..be7f59998c --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/agent/main.cpp @@ -0,0 +1,17 @@ +/* + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include + +#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE 1 + +#include "pkagentexample.h" + +int main(int argc, char *argv[]) +{ + PkAgentExample example(argc, argv); + return example.exec(); +} diff --git a/local/recipes/libs/polkit-qt6/source/examples/agent/pkagentexample.cpp b/local/recipes/libs/polkit-qt6/source/examples/agent/pkagentexample.cpp new file mode 100644 index 0000000000..da555c75e1 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/agent/pkagentexample.cpp @@ -0,0 +1,15 @@ +#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE 1 + +#include +#include "pkagentexample.h" +#include +#include +#include + +PkAgentExample::PkAgentExample(int &argc, char **argv) + : QCoreApplication(argc, argv) +{ + PolkitQt1::UnixSessionSubject session(getpid()); + + m_listener.registerListener(session, "/org/kde/PolicyKit1/AuthenticationAgent"); +} diff --git a/local/recipes/libs/polkit-qt6/source/examples/agent/pkagentexample.h b/local/recipes/libs/polkit-qt6/source/examples/agent/pkagentexample.h new file mode 100644 index 0000000000..a08d808c21 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/agent/pkagentexample.h @@ -0,0 +1,28 @@ +// This is an example not a library +/* + SPDX-FileCopyrightText: 2008 Daniel Nicoletti + SPDX-FileCopyrightText: 2009 Radek Novacek + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#ifndef PKAGENTEXAMPLE_H +#define PKAGENTEXAMPLE_H + +#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE 1 + +#include +#include "klistener.h" + +class PkAgentExample : public QCoreApplication +{ + Q_OBJECT +public: + PkAgentExample(int &argc, char **argv); + ~PkAgentExample() override {}; +private: + KListener m_listener; +}; + + +#endif diff --git a/local/recipes/libs/polkit-qt6/source/examples/icons/action-locked-default.png b/local/recipes/libs/polkit-qt6/source/examples/icons/action-locked-default.png new file mode 100644 index 0000000000000000000000000000000000000000..e334fb6aca15dac77522fba46c653af213bbf983 GIT binary patch literal 1686 zcmV;H25I?;P)2>|STMG} z$Y|8Jg0@wP;0GD(%U}$0V{Nucv9W3mj7CtKt<8|BWm!7AOhc>T(pj0BdOWxH_@4d# zFZN;sZyDPkew_21^FGi2_rE`{Argt;{}eOkDd*3hFA4+#Z(1ytSL}9szQJI?`1ttE zfq{W$r_*_Q=gyt2cn+D52aNUg^&gr{rV6*)Z3za07#<$R{_V$K}s_omi zzYjotkpzqvE?l@otJh6TOyKe3$FN$hcq+2j=kp;P4rAlSjktI3Ufbr)n~N4g!iZU< zp`qarUA?ZqzaL(&7dD&iHh^tZoJvBeqobqSsQizZm>AU7)*?PWzOb>e@z4wLKwVwk z%MOR5o)+4u2=qdANlD3mG5p_W96WgNGndP?Up%p9%^HQ|ir24S-@GUfghHW80JcYu z9zju*z8RE@L`q9b%jltQ2?uk;LZd1d9Rjo2oS~|!9EjN1*mq`7u9G0)GNaK5zuylM z$XGN1W_>!#4g!{4Bjyl3e^Dxf?w4>ao&c>`A}-~jk*!;|j$sbjw{M?3ql}D<2$|T$ z641+xnUDDjJtc&3%ICkuqcwsFoqlqM5|IY}pC8N2y zSxelgsHnHuo{tt46`dxDz0WlZXvKm;Abo(12qI%+W25X3@0FLA-$_kPts;qR0Obs; zI%^~P_LE(q<;zx>`W}oJ1O5ppN*F0gF1BC`4Eint&lYAdq~M32+wk@G=OE&A*zoR- z4dDZa&soaK%HE)!<25xk^(@yCAu%I?s>*GV1h)%`3GqmOX&Ky!>99MaVbqkWP{Sc2 z2oa;%27}20IU=Me_~5_^oH<*E!NEa@L_2Np`hpqMaevRAJ!@H>7pkkPk8{0u))1&F zn9VB2h6fN)v>5=0Gm1o(ASyNiX8TeoK_3F%Vfe=$BH;Jpde?neZB7&y7o(}ENh(5y z6DU8?{jXB#HImrDl0M0GFV_cVOhTjaDU2G(Tsk9Rg2@np2?`8q0A$Di4f-C*0r6;F zULJ;qhLD+=35thkrqT?C;A}!dLTPSp?nhj|HD?mC6$_-cpZRVe-I1h`T6i2N=}6oV7Ccn`L0c@1>25Rh<)VhNoz zr>AE`5huAO{uA|stx zu~b28PcWUA70Z(+PyU>97R-?kdS!_8k4GapBO7h)9b&a4qV`PJjcYh_;#2ksFDzyw z`Y59OdB^c|H%{yM5hSN)q2*EwJoz5ny?a+`UsGOJTMZNYLv%D7m&3N07Zbe-^rVv( zG!%$tGG(CcN-OeL<>PkOZLG{&i5u-LIDhI(IPHMlm8dl+uU}a>fk`!jFxzm5F_r;i z35H-aQMthcI6O#6qve-dke{EA&aO_)^6PCE@$2at#70}-cCl4k%?NOxqIwrjAQYN} z&nMl?2TmH2P%*)ETv{fUrDvnHwH2#Zt;Vfew~(8Yi|f}e;+IojA;xJ%ygQDrcWQ&l zPXdvMVc`UV3JC-hS{e!EbPUE@wUqpCE}*RO~mq|@p)lkq2uPwo5;$_l8HCCd-v{3Llgj`#F${} z`^Yp5P5thruE`k)%)yev*R$^S_I6iNQqp)&PfuS(Ma5~p8T+JIrXYuhr{E_hgwtX*L9!eayjqx^b|)&M^H+kP$-1h-Q5icFDEA_p99cI5|C?aYahw^(8x3?EM@;q;goQ?zN zqvyWk0+^nbUOWdVq#(j!1))& z!otEUaz4XK3=R(Zq}IdX;o*&z6sXl|^R)Z)!NCDb{4;ib!OYy;+$<@wO=S5!55RoO zA)vVTbF4Y(Iy*a`o^yVI1g)EuQleU|a&Gh|LEskc1`H~*_qfCy$NAv&MQoyGYWinlfQ~`y6lMh!kR*DIOEfE47Q#$oLdvWTe)=w*kl74*JWsUp5Zr@ZbYtw3r~<>_!>FDE0pNMs=0FU)dpq9ZZP-kCT3pK{60?7kfc+kbGn@%|7H-rw zz_E}Pjlvs(won#91N^9EkY9}`357jlBd6z(vTd6CjC12?aCT?p`43I?!25NL$PrGd5)m3BiL#8wa)_eN+? z+*n$=k=9`ua0dZ}MnKtD*$g5CBtT+-B#@O#s_s3L~*gD7e*7b!`{(|1f}+8x1(K437T`gNKXRFeq;L?dPc`JSy;kd3|R%%Z&X* z#~V(Rw=^V2%M4w37(-&2;XuYBLs59Pp?CgxGk@Xo9P_9Ag`b${8_Sj$RyO$D(67ln zgQHyxUh7llUpRn8}_|y;d1OtQ|rO1C5G#Qr%gQ4J;(TQx0!W|HXbp<(kJ&dRYO18Y#1LsY?#w+ zjDfa^hM$eY&*YtR1{%f<hG=2V>_L})*YG8};v!=DFp5mM_1MeQV&&(>=`+ZE%8}HV*XM!&$Wt)jz zHP_t!VRWk5oN)UjQ}EI6Hk*R=&F(atYhCkabNfs;*Gz1jk!pf}+2%9e=)|$+k&oPb z(`{quYvX0#alwf9UxNrvH~)f1V18c%ne_}f6O1q2NiuHnr6Xp}&NR%p?%%IBkkG~~ zZE)(J=B|Qz=Zvo^KF!Y!iMNuyU z=}(v&Pq*%1Kz@u{xF^*xxM4HHXaDC7cyqadqRocm-$V?ptEZZjUq3v}eCN7fn0o6@ z95d&8_Mc$dm3!&t;-UNk!-4ofL+3!;z@8ljq>%x=*03#Uw4rA>W>Q~2k!^Opk^ZG= zyr{)lbGFYn|1j5moG{vy-d4N9a6oz)IzQCO{2w-;s<#1mfuXVQumOK_e2eInyRPE2O217Vfc;0=P@EWTJO;@boV#) zXZl+}Bqwqra*Fce2a3lRKcz2K+*5IP#c1wy2fKsZn{nyE4fF+aF#ny~ciz!$#7lrk z6E0E0vjlO0A~tbevxkfs+HKhROWBli8DTbw{D6nhj}g@8!AE91JmaAm{8tKDWPZT_ z)-0OmjBWtsmrEbeY$W&X%U@OuN97LvO#dcnM`xW{r+G@pH(M6Sufr+D~vLv26cvq&D%s%+&U#^c5(s%Vm zZ!Gw>o*cX=3ZXrrMd4&5;q63;JdW!h8psPTB4N+&<6SFWmv3~3j0wF@+r;Ld#S+mJ>-qn816Auj2!wY6l?eyM@bn*YY|A20xsO_3g%~~ZOk%K9hBcsp<8&7{~ z>+~x)17`m4^5ZkVhLY}=vM#kFdc4o^p*hV6vy>(JY5K!=_rAN?Jx?7gh&-5dSJM94 zA6FbMKVH%E%u_69HR)|5)qjiqJ@)bC=X@_Y&p25u^?UxfzkpFgwhkG1OE&-C`Q;l> zF{P}THX%KCVs5wWa*D$PWoFV?=U2-{O#3LXATn`Ylf_$GzmV2P`?wjLk#gr6-L7jO z9133L)Nz`YPC4n@JTiT*Ja=irq2?9iE0f|Cy2KeA9dmhp*?kQA>-axaTzia=ey<0; zJrHz)Z9|zgy(Tm+v2#r~3cZ;09t1W7(^7YU-~SSFrxn($k5NmK7Dn zU--L1#fplDyx9$gx)a>AiZ2guu595O7E08*-ZRxNMfbAZJ?-rbZ062bf460<6{35* z3En@z>Eb)(-wpmr-c*?d&Jrp0?uXFy;NXg0ko3pMwzCgH@`#i_axd-l4(&{t*0HS2Kb% zzV)u64md|Cj@OqP`B2}NW@$r{bJCwaf1=ii;2qVk9GXlx*1oh>VSA#LwJT>hsZNuU ztc3i~6KTsU)>O=M?uE*mE=T1k#F|xa;8F1I(v7+h{Ih*q^koRl4{UJyLugiT8j+gL z3|7+_5(m{97$#tnl$d@^p(8|H=-$psJtli*#NYZ0rcb|Q7&;o>$;D{yZOgMtkQiY z^nez*59s~AO5g@r5YOU_ugbTyq7i9<5&mz>))EXq6ZlQpgCryd!)wcKC!G93q3Zua8WhTJ2M5TsZZ$$shq*U}3=dgZ?b3MnE1(SoU-qRv`L^OjTSoObpx zK%$cAJjwtdR--`jad7EGI=N)i3W!ocB68*L0sa~;kU|<2K$u!Y0hbtl;6446dca;i zBt1c2&}*d>_?k^j0}3c18}yK_*ZIIv-jV^pr`*g{Ku6+y4E&AO`UuECnME-;SrTVG z$epa`6i5$QP6o(!In50qD`YWEL3WX&QQ%WbBm%rlefj~%IYk6G#8Co3h#RSbD<43F zMB+eu+EEEKlr${mJb?o`lJ2ws?{_*wD#1(E0_gzW7A=u_;I7uQvJ$kT9^gsPo4wh3 z5xjf#*Bk-bddsK{I$XQR4d6w*RrCV)gqKHiaHczN(gt*bhG`65j;>@Pc$>Vn@_Xg1eG$#{4*RcTsRoLFScBTCNr)5R%yOD&8*oyjug(Og zT-19RWQ<&tV<64sUFw2dE#0*ciU4a9vA`xU6L9&2+YEc0)pE6niZ_9oB8Dt#0 zCjKY%P{IuW25wFv`jd5N>YDoXJK^=VK1m;58-;6s5#B3MUA z!V<3`KpE!&bhqZv0N90M-H-tJAfsr?HlPOsI0ICYP9<<1jko{^t@sY`OHV!m0{Gbr zTtzzjfJE{r0CKoQ8(;<7xgJ={m(me9pl75ms9k>n;1XrHKzmvd1lrP)Fpx+BzF)Ed zUJU`tYgm`or~-lnNC7gaM;_3KWDWuQ*~CHM5G}Y1bQVfCU>ar87j!w_GYaUfqnQPa zm#@eIp3{$|1Mm=c(h$2%3OEl;(#HBZ=qoJd1n404;RD9%eq10RsVGP$k4py72w^Z# zLN%v=GU7ylAVRHQGJs$W7idCr%7HK$ctD&g1hj(=;TF(?G?&joXKQ0g1MgK$a;AXS zOdHBc@OJAc-UVH#N9hONTRbRTK*m$WHQ?n@k1n8p(vS2j&bs67pMgU zNu(NNy}ZjtaE3`(Zv|N?t#v(i1{8Yz!3oQHF9^RJr!K1CrsL180W}^3uRrDBpX31i4L)>2`3s$XN}7l(Jk00Uyg-dJq`Gt&#yG z6Zz@XFT?>(a|Qt}*RYoVle0;$U(s0j8QplxU8$1pgQTH(@;V<-u%XE!<8n$L;oIRPcaueB3}nv0*+vR-=9 z9^zkk{dFF}^gk!x8#?+w4QT89&sbCrU-UE0kusT9c@&)ATT%B;9*QbEt>U z+o;ua(n>E~EBTTFebW1Y`kZ5+zQnV-Oyk-`m-$QdDsI&4OJ0edia()Wb94Rrk+V)d zc8&Skhk)O&ZmyGXJph2K?HlaB-Rq!&;S<{mEG61_TB<=!8itzUXo?hUcA?rAs4`%U%Gc>Q?Ycv@_!x5mUB zKUj1a%Z;0_x9U(GR2}!~dG+*px3}*a-!j(5UWiVpo=`n9TJM9FtG_$)aOu6eL*Mn~ z_y==@^jdy@9bTX~wBDaboO8|r->0k&taft!C;U$bHabuEUh}u}A9mhxUh{qBye+ew zbCM%lWrO^nZ_tB)B2D?NY%?PN(TTo W*alb-Q_5Tb0000+&AqeV`TpmBzkBYt_f7!tukznEK*4AHqXsB=gbtxkOy|(&e&fAR0~FeX zu_8&4-re0bOraVX89{Gv?{JzjHJgpGoab(UyXu$LP?T4cb@li6gNozPqeo!Dj)Q}P zsIIBLy?XWPH7r-t)zGByB*OUMK}pQjrmMqu@Al$OTO0DXY{9v?bCF_WgCZ9f-0SE- zUtb@tU2A?A7i_j&EoHjeTDU#0Kyndq<9i8o{j*dcv(d&@W)NCS` zP!KXBBh<%4qrJTiR~j22i;rt_badRsG&n6SjSMi?dU|^1o?_2PMUuR`zM)pt(%Ous zx*8;WVT({6Z?s@3(L&rJ>WEAtl8xEgqN=0_6%}PDD9l%#iVVNwzSBLPG~Z>~e`|ni zvUzfO;)B}yYScB~QJcO&prIj-Qu7js3o$9Q^a9?eVpF#B{F2O z$jZt;KN|4O2E+^I!;Q~}52dl<@!XPE5jTlGLPgx=R->Fy zawa6iUYhG+H48rk_+zuP(>vr^8FU7whcSHZpC3_p~N_ z#eU=Z^UQ!`)pG3P48##RbmhZTeAGmDH}dDqM#1#AFu)Zb?(D>cS(Z>fVL&|J1|D7_ ztX%n75!2S>DbQQCY-yx2GZ~>So8d(%KM}E9ljYEr4^#2cf;~OxZ+%>Rh>B;?{l3hf zfOPgm5CO#Zt5!hdu^S5)eh|;JH8G$&b?Vfe@rf}bagrZL4M?9bP^QI0I$inj?H+)O zp{`COy=R5SNqjawx&jfL0YB$W_||=g%GlU=H`CU{fHtu}?CsH-nU#tICT}8`(xQk= z9vPU(L-I^hJhN_(raO3+9N*2WD30UBS?Mg}c^ zDUHRj+eNv@cDk|0Pi1Ci7R0p1{CCVX<6<9Q@s0e#TqJLI#m|%;O(at<dgFOU13bdez`$Tv$f1MxYig^|P+5TzX$UTCbs@H*BqRjo zmkN+`KASqU4@z?WI(669&XuyY+TeC&Nw*jj$zr wIc&M#gk$|Ud6rKy0inww81Eszb1L91}H`m zR=Ih(CptUt3{VUW4i2KbyL;exfxejCW6!*B1ANr4E~U6wQ+=neuMd@NGRMl0WrluO_%FBihq-(nT{Qb0~ z`7YCbssTR9X6baS`6{MboinVg0|0Uo<5 zcR|q5^+ZB08d$Gb2VcLr>ny z_y}N~&s=4W+S|2Y(fgWU^H$ zdy@LJg;^NmKZZsmwq1(^3pCtm0C?;!-wnwL34{i^Uqqyd&B}O(F@jXv;k{|&L(+0) znjVX@g*{$PpbyUoy?*Fbty3ZaFrSMueVAXdvxX$NIw zIGk22Z)93b(_jPK#A`OTHc|Pe zIycu2roptHbw6NkYikp$%RM|;R(S@WrF<&(c_k6Ums=9AN|e|wKTiG#NvR2}`wdy! zSSK=#=h=|FLQLPV!L7Euq7(%cdc32WDw+r*BDk4wapY5Cra+UE26dvEwcaN7F4K5s z1K^Fx*x2~1@QAR^pQN*Dn)%8H^lSiohmgF;O{pbC zNJL~rcYQ-0uC`oZ`#-d{wxFr`GAgSopj1ZmQp;7aXGgXvHQa<5vCL_O)1`fBdmogY zD;+E=D;?DAPwRJfUUiw> + + action-locked-default.png + action-locked.png + action-unlocked.png + custom-no.png + custom-yes.png + + diff --git a/local/recipes/libs/polkit-qt6/source/examples/main.cpp b/local/recipes/libs/polkit-qt6/source/examples/main.cpp new file mode 100644 index 0000000000..6968c70def --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/main.cpp @@ -0,0 +1,18 @@ +// This is an example not a library +/* + SPDX-FileCopyrightText: 2009 Daniel Nicoletti + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include + +#include "PkExample.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + PkExample example; + example.show(); + return app.exec(); +} diff --git a/local/recipes/libs/polkit-qt6/source/examples/mainHelper.cpp b/local/recipes/libs/polkit-qt6/source/examples/mainHelper.cpp new file mode 100644 index 0000000000..7d2a3f0c0c --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/mainHelper.cpp @@ -0,0 +1,14 @@ +// This is an example not a library +/* + SPDX-FileCopyrightText: 2009 Daniel Nicoletti + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "PkExampleHelper.h" + +int main(int argc, char *argv[]) +{ + PkExampleHelper example(argc, argv); + return example.exec(); +} diff --git a/local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.conf b/local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.conf new file mode 100644 index 0000000000..304d269f6e --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.conf @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + diff --git a/local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.policy b/local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.policy new file mode 100644 index 0000000000..e42430c844 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.policy @@ -0,0 +1,81 @@ + + + + KDE + http://www.kde.org + + + Kick + Prevents PolicyKit-Qt example from kicking + + no + no + + + + + Cry + Prevents PolicyKit-Qt example from crying + + no + yes + + + + + Bleed + Prevents PolicyKit-Qt example from bleeding + + no + auth_self + + + + + Play + Prevents PolicyKit-Qt example from playing + + no + auth_admin + + + + + Listen + Prevents PolicyKit-Qt example from listening + + no + auth_self_keep + + + + + Delete + Prevents PolicyKit-Qt example from deleting + + no + auth_admin_keep + + + + + Push + Prevents PolicyKit-Qt example from setting permissions for the shout action + + no + auth_admin_keep + + + + + Shout + Prevents PolicyKit-Qt example from shouting + + no + yes + + foo + + diff --git a/local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.policy.in b/local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.policy.in new file mode 100644 index 0000000000..ddab0a9f23 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.policy.in @@ -0,0 +1,85 @@ + + + + KDE + http://www.kde.org + + Kick + Prevents PolicyKit-Qt example from kicking + + no + no + + + + Cry + Prevents PolicyKit-Qt example from crying + + no + yes + + + + Play + Prevents PolicyKit-Qt example from playing + + no + auth_self + + + + Bleed + Prevents PolicyKit-Qt example from bleeding + + no + auth_admin + + + + Listen + Prevents PolicyKit-Qt example from listening + + no + auth_self_keep + + + + Delete + Prevents PolicyKit-Qt example from deleting + + no + auth_admin_keep + + + + diff --git a/local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.service.in b/local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.service.in new file mode 100644 index 0000000000..cf722c2fca --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.service.in @@ -0,0 +1,5 @@ +[D-BUS Service] +Name=org.qt.policykit.examples +Exec=@BIN_INSTALL_DIR@/@POLKITQT-1_EXAMPLE_HELPER@ +User=root + diff --git a/local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.xml b/local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.xml new file mode 100644 index 0000000000..1e16316c2e --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/examples/org.qt.policykit.examples.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/local/recipes/libs/polkit-qt6/source/gui/CMakeLists.txt b/local/recipes/libs/polkit-qt6/source/gui/CMakeLists.txt new file mode 100644 index 0000000000..69ec1f6a71 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/gui/CMakeLists.txt @@ -0,0 +1,38 @@ +add_library(${POLKITQT-1_GUI_PCNAME} SHARED) +add_library(${POLKITQT-1_CAMEL_NAME}::Gui ALIAS ${POLKITQT-1_GUI_PCNAME}) + +target_sources(${POLKITQT-1_GUI_PCNAME} PRIVATE + polkitqt1-gui-action.cpp + polkitqt1-gui-actionbutton.cpp + polkitqt1-gui-actionbuttons.cpp +) + +generate_export_header(${POLKITQT-1_CORE_PCNAME} + BASE_NAME polkitqt1-gui + EXPORT_FILE_NAME polkitqt1-gui-export.h +) + +target_link_libraries(${POLKITQT-1_GUI_PCNAME} + PUBLIC + ${POLKITQT-1_CORE_PCNAME} + Qt${QT_MAJOR_VERSION}::Widgets + PRIVATE + Qt${QT_MAJOR_VERSION}::Core + Qt${QT_MAJOR_VERSION}::DBus +) + +set_target_properties(${POLKITQT-1_GUI_PCNAME} PROPERTIES VERSION ${POLKITQT-1_LIBRARY_VERSION} + SOVERSION ${POLKITQT-1_ABI_VERSION} + DEFINE_SYMBOL MAKE_POLKITQT1_LIB + EXPORT_NAME Gui) + +target_include_directories(${POLKITQT-1_GUI_PCNAME} + INTERFACE + $ + $ + $ +) + +install(TARGETS ${POLKITQT-1_GUI_PCNAME} EXPORT ${POLKITQT-1_CAMEL_NAME}Export ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION bin) diff --git a/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-action.cpp b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-action.cpp new file mode 100644 index 0000000000..38354b08d9 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-action.cpp @@ -0,0 +1,502 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Daniel Nicoletti + SPDX-FileCopyrightText: 2009 Dario Freddi + SPDX-FileCopyrightText: 2009 Jaroslav Reznik + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "polkitqt1-gui-action.h" +#include "polkitqt1-authority.h" +#include "polkitqt1-subject.h" + +#include + +namespace PolkitQt1 +{ + +namespace Gui +{ + +/** + * \internal + */ +class Q_DECL_HIDDEN Action::Private +{ +public: + Private(Action *p); + + Action *parent; + + QString actionId; + Authority::Result pkResult; + qint64 targetPID; + + void updateAction(); + bool computePkResult(); + void configChanged(); + + bool initiallyChecked; + + // states data + bool selfBlockedVisible; + bool selfBlockedEnabled; + QString selfBlockedText; + QString selfBlockedWhatsThis; + QString selfBlockedToolTip; + QIcon selfBlockedIcon; + + bool noVisible; + bool noEnabled; + QString noText; + QString noWhatsThis; + QString noToolTip; + QIcon noIcon; + + bool authVisible; + bool authEnabled; + QString authText; + QString authWhatsThis; + QString authToolTip; + QIcon authIcon; + + bool yesVisible; + bool yesEnabled; + QString yesText; + QString yesWhatsThis; + QString yesToolTip; + QIcon yesIcon; +}; + +Action::Private::Private(Action *p) + : parent(p) + , targetPID(getpid()) +{ + initiallyChecked = false; + + // Set the default values + selfBlockedVisible = true; + selfBlockedEnabled = false; + + noVisible = true; + noEnabled = false; + + authVisible = true; + authEnabled = true; + + yesVisible = true; + yesEnabled = true; +} + +Action::Action(const QString &actionId, QObject *parent) + : QAction(parent) + , d(new Private(this)) +{ + // this must be called AFTER the values initialization + setPolkitAction(actionId); + + // track the config changes to update the action + connect(Authority::instance(), SIGNAL(configChanged()), + this, SLOT(configChanged())); + // for now we call config changed.. + connect(Authority::instance(), SIGNAL(consoleKitDBChanged()), + this, SLOT(configChanged())); +} + +Action::~Action() +{ + delete d; +} + +bool Action::activate() +{ + switch (d->pkResult) { + case Authority::Yes: + case Authority::Challenge: + // just Q_EMIT the 'activated' signal + Q_EMIT authorized(); + return true; + break; + default: + case Authority::No: + if (d->noEnabled) { + /* If PolicyKit says no... and we got here.. it means + * that the user set the property "no-enabled" to + * TRUE.. + * + * Hence, they probably have a good reason for doing + * this so do let the 'activate' signal propagate.. + */ + Q_EMIT authorized(); + return true; + } + break; + } + return false; +} + +void Action::setChecked(bool checked) +{ + // We store this as initiallyChecked + // to be able to undo changes in case the auth fails + d->initiallyChecked = checked; + QAction::setChecked(checked); +} + +void Action::Private::updateAction() +{ + if (Authority::instance()->hasError()) { + return; + } + + switch (pkResult) { + default: + case Authority::Unknown: + case Authority::No: + qobject_cast(parent)->setVisible(noVisible); + qobject_cast(parent)->setEnabled(noEnabled); + qobject_cast(parent)->setText(noText); + if (!noWhatsThis.isNull()) { + qobject_cast(parent)->setWhatsThis(noWhatsThis); + } + if (!noToolTip.isNull()) { + qobject_cast(parent)->setToolTip(noToolTip); + } + qobject_cast(parent)->setIcon(noIcon); + break; + + case Authority::Challenge: + qobject_cast(parent)->setVisible(authVisible); + qobject_cast(parent)->setEnabled(authEnabled); + qobject_cast(parent)->setText(authText); + if (!authWhatsThis.isNull()) { + qobject_cast(parent)->setWhatsThis(authWhatsThis); + } + if (!authToolTip.isNull()) { + qobject_cast(parent)->setToolTip(authToolTip); + } + qobject_cast(parent)->setIcon(authIcon); + break; + case Authority::Yes: + qobject_cast(parent)->setVisible(yesVisible); + qobject_cast(parent)->setEnabled(yesEnabled); + qobject_cast(parent)->setText(yesText); + if (!yesWhatsThis.isNull()) { + qobject_cast(parent)->setWhatsThis(yesWhatsThis); + } + if (!yesToolTip.isNull()) { + qobject_cast(parent)->setToolTip(yesToolTip); + } + qobject_cast(parent)->setIcon(yesIcon); + if (parent->isCheckable()) { + qobject_cast(parent)->setChecked(!initiallyChecked); + } + break; + } + Q_EMIT parent->dataChanged(); +} + +void Action::Private::configChanged() +{ + bool result_changed; + result_changed = computePkResult(); + if (result_changed) { + updateAction(); + } +} + +bool Action::Private::computePkResult() +{ + Authority::Result old_result; + UnixProcessSubject subject(parent->targetPID()); + + old_result = pkResult; + pkResult = Authority::Unknown; + + pkResult = Authority::instance()->checkAuthorizationSync(actionId, subject, Authority::None); + + return old_result != pkResult; +} + +qint64 Action::targetPID() const +{ + if (d->targetPID != 0) { + return d->targetPID; + } else { + return QCoreApplication::applicationPid(); + } +} + +void Action::setTargetPID(qint64 pid) +{ + d->targetPID = pid; + + d->computePkResult(); + d->updateAction(); +} + +bool Action::isAllowed() const +{ + return d->pkResult == Authority::Yes; +} + +bool Action::is(const QString &other) const +{ + return d->actionId == other; +} + +void Action::revoke() +{ + /*TODO: implement it? no negative authorizations available, no authorization db*/ +} + +void Action::setText(const QString &text, States states) +{ + if (states & All) { + d->selfBlockedText = text; + d->noText = text; + d->authText = text; + d->yesText = text; + } else if (states & Auth) { + d->authText = text; + } else if (states & No) { + d->noText = text; + } else if (states & SelfBlocked) { + d->selfBlockedText = text; + } else if (states & Yes) { + d->yesText = text; + } + + d->updateAction(); +} + +QString Action::text(Action::State state) const +{ + switch (state) { + case Yes: + return d->yesText; + case No: + return d->noText; + case Auth: + return d->authText; + case SelfBlocked: + return d->selfBlockedText; + case None: + return QAction::text(); + default: + return QString(); + } +} + +void Action::setToolTip(const QString &toolTip, States states) +{ + if (states & All) { + d->selfBlockedToolTip = toolTip; + d->noToolTip = toolTip; + d->authToolTip = toolTip; + d->yesToolTip = toolTip; + } else if (states & Auth) { + d->authToolTip = toolTip; + } else if (states & No) { + d->noToolTip = toolTip; + } else if (states & SelfBlocked) { + d->selfBlockedToolTip = toolTip; + } else if (states & Yes) { + d->yesToolTip = toolTip; + } + + d->updateAction(); +} + +QString Action::toolTip(Action::State state) const +{ + switch (state) { + case Yes: + return d->yesToolTip; + case No: + return d->noToolTip; + case Auth: + return d->authToolTip; + case SelfBlocked: + return d->selfBlockedToolTip; + case None: + return QAction::toolTip(); + default: + return QString(); + } +} + +void Action::setWhatsThis(const QString &whatsThis, States states) +{ + if (states & All) { + d->selfBlockedWhatsThis = whatsThis; + d->noWhatsThis = whatsThis; + d->authWhatsThis = whatsThis; + d->yesWhatsThis = whatsThis; + } else if (states & Auth) { + d->authWhatsThis = whatsThis; + } else if (states & No) { + d->noWhatsThis = whatsThis; + } else if (states & SelfBlocked) { + d->selfBlockedWhatsThis = whatsThis; + } else if (states & Yes) { + d->yesWhatsThis = whatsThis; + } + + d->updateAction(); +} + +QString Action::whatsThis(Action::State state) const +{ + switch (state) { + case Yes: + return d->yesWhatsThis; + case No: + return d->noWhatsThis; + case Auth: + return d->authWhatsThis; + case SelfBlocked: + return d->selfBlockedWhatsThis; + case None: + return QAction::whatsThis(); + default: + return QString(); + } +} + +void Action::setIcon(const QIcon &icon, States states) +{ + if (states & All) { + d->selfBlockedIcon = icon; + d->noIcon = icon; + d->authIcon = icon; + d->yesIcon = icon; + } else if (states & Auth) { + d->authIcon = icon; + } else if (states & No) { + d->noIcon = icon; + } else if (states & SelfBlocked) { + d->selfBlockedIcon = icon; + } else if (states & Yes) { + d->yesIcon = icon; + } + + d->updateAction(); +} + +QIcon Action::icon(Action::State state) const +{ + switch (state) { + case Yes: + return d->yesIcon; + case No: + return d->noIcon; + case Auth: + return d->authIcon; + case SelfBlocked: + return d->selfBlockedIcon; + case None: + return QAction::icon(); + default: + return QIcon(); + } +} + +void Action::setEnabled(bool enabled, States states) +{ + if (states & All) { + d->selfBlockedEnabled = enabled; + d->noEnabled = enabled; + d->authEnabled = enabled; + d->yesEnabled = enabled; + } else if (states & Auth) { + d->authEnabled = enabled; + } else if (states & No) { + d->noEnabled = enabled; + } else if (states & SelfBlocked) { + d->selfBlockedEnabled = enabled; + } else if (states & Yes) { + d->yesEnabled = enabled; + } + + d->updateAction(); +} + +bool Action::isEnabled(Action::State state) const +{ + switch (state) { + case Yes: + return d->yesEnabled; + case No: + return d->noEnabled; + case Auth: + return d->authEnabled; + case SelfBlocked: + return d->selfBlockedEnabled; + case None: + return QAction::isEnabled(); + default: + return false; + } +} + +void Action::setVisible(bool visible, States states) +{ + if (states & All) { + d->selfBlockedVisible = visible; + d->noVisible = visible; + d->authVisible = visible; + d->yesVisible = visible; + } else if (states & Auth) { + d->authVisible = visible; + } else if (states & No) { + d->noVisible = visible; + } else if (states & SelfBlocked) { + d->selfBlockedVisible = visible; + } else if (states & Yes) { + d->yesVisible = visible; + } + + d->updateAction(); +} + +bool Action::isVisible(Action::State state) const +{ + switch (state) { + case Yes: + return d->yesVisible; + case No: + return d->noVisible; + case Auth: + return d->authVisible; + case SelfBlocked: + return d->selfBlockedVisible; + case None: + return QAction::isVisible(); + default: + return false; + } +} + +void Action::setPolkitAction(const QString &actionId) +{ + //TODO: + d->actionId = actionId; + + d->computePkResult(); + d->updateAction(); +} + +//-------------------------------------------------- + +QString Action::actionId() const +{ + return d->actionId; +} + +} + +} + +#include "moc_polkitqt1-gui-action.cpp" diff --git a/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-action.h b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-action.h new file mode 100644 index 0000000000..3caa1ab99d --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-action.h @@ -0,0 +1,291 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Daniel Nicoletti + SPDX-FileCopyrightText: 2009 Dario Freddi + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef POLKITQT1_GUI_ACTION_H +#define POLKITQT1_GUI_ACTION_H + +#include "polkitqt1-gui-export.h" + +#include + +namespace PolkitQt1 +{ + +namespace Gui +{ + +/** + * \class Action polkitqt1-gui-action.h Action + * \author Daniel Nicoletti + * \author Dario Freddi + * + * \brief Class used to manage actions + * + * This class is an interface around PolicyKit Actions. + * By using this class, you are able to track the result of a + * given action. + * + * Most of the times, you would want to use this class combined + * with a QAbstractButton. In this case, you can use the more + * comfortable ActionButton class that manages button's properties + * update for you. + * + * \see ActionButton + */ +class POLKITQT1_GUI_EXPORT Action : public QAction +{ + Q_OBJECT + Q_DISABLE_COPY(Action) +public: + + enum State { + None = 0, + SelfBlocked = 1, + Yes = 2, + No = 4, + Auth = 8, + // Future usage = 16, + // Future usage = 32, + // Future usage = 64, + // Future usage = 128, + // Future usage = 256, + All = 512 + }; + Q_DECLARE_FLAGS(States, State) + + /** + * Constructs a new Action item + * + * \param actionId the PolicyKit action Id (e.g.: org.freedesktop.policykit.read) + * \param parent the object parent + */ + explicit Action(const QString &actionId = QString(), QObject *parent = nullptr); + ~Action() override; + +Q_SIGNALS: + /** + * Emitted when the PolicyKit result (PolKitResult) + * for the given action or the internal data changes + * (i.e. the user called one of the set methods). + * You should connect to this signal if you want + * to track these changes. + */ + void dataChanged(); + + /** + * Emitted when using this class as a proxy + * for a given action, It's only emitted if the + * activate() slot is called and the auth permits + * the action + * + * \see activate() + */ + void authorized(); + +public Q_SLOTS: + /** + * Use this slot if you want to activate + * the action. authorized() will be emitted + * if the action gets authorized. + * + * \return \c true if the caller can do the action + * + * \see authorized() + */ + bool activate(); + + /** + * Defines the checked state. The opposite state will + * trigger authentication for this actions. For example, if + * you set this to \c true, when the action's checked state + * will become \c false, the authentication will be triggered. + * + * \param checked the new checked state + */ + void setChecked(bool checked); + + /** + * This method can be used to revoke the authorization + * obtained for this action. + */ + void revoke(); + +public: + /** + * Changes the action being tracked + * + * \param actionId The new action ID + */ + void setPolkitAction(const QString &actionId); + + /** + * Returns the current action ID. + * + * \return The action ID + * + */ + QString actionId() const; + + /** + * Sets the text for the current action. This will + * be shown only in the states specified in the \c states parameter. + * \param text the new text for the action + * \param states the states of the Polkit action on which the setting + * will be applied + */ + void setText(const QString &text, States states = All); + + /** + * Sets the tooltip for the current action. This will + * be shown only in the states specified in the \c states parameter. + * \param toolTip the new tooltip for the action + * \param states the states of the Polkit action on which the setting + * will be applied + */ + void setToolTip(const QString &toolTip, States states = All); + + /** + * Sets the whatsthis for the current action. This will + * be shown only in the states specified in the \c states parameter. + * \param whatsThis the new whatsthis for the action + * \param states the states of the Polkit action on which the setting + * will be applied + */ + void setWhatsThis(const QString &whatsThis, States states = All); + + /** + * Sets the icon for the current action. This will + * be shown only in the states specified in the \c states parameter. + * \note You need to pass a QIcon here. You can easily + * create one from a Pixmap, or pass a KIcon + * \param icon the new icon for the action + * \param states the states of the Polkit action on which the setting + * will be applied + */ + void setIcon(const QIcon &icon, States states = All); + + /** + * Sets whether the current action is visible or not. This will + * be applied only in the states specified in the \c states parameter. + * \param visible visibility of the action + * \param states the states of the Polkit action on which the setting + * will be applied + */ + void setVisible(bool visible, States states = All); + + /** + * Sets whether the current action is enabled or not. This will + * be shown only in the states specified in the \c states parameter. + * \param enabled whether the Action will be enabled or not + * \param states the states of the Polkit action on which the setting + * will be applied + */ + void setEnabled(bool enabled, States states = All); + + /** + * This function sets the process id of the target that + * should receive the authorization. Set this to 0 to set + * the current process as the target. + * + * \param pid The target process id; 0 if it is the current process + */ + void setTargetPID(qint64 pid); + + /** + * Gets the text of the action when it is in the specified state + * + * \note Passing None will return the current value + * \param state The state to be checked + * \returns The text shown when the action is in the specified state + */ + QString text(State state = None) const; + + /** + * Gets the tooltip of the action when it is in the specified state + * + * \note Passing None will return the current value + * \param state The state to be checked + * \returns The tooltip shown when the action is in the specified state + */ + QString toolTip(State state = None) const; + + /** + * Gets the whatsThis of the action when it is in the specified state + * + * \param state The state to be checked + * \returns The whatsThis shown when the action is in the specified state + */ + QString whatsThis(State state = None) const; + + /** + * Gets the icon of the action when it is in the specified state + * + * \note Passing None will return the current value + * \param state The state to be checked + * \returns The icon shown when the action is in the specified state + */ + QIcon icon(State state = None) const; + + /** + * Gets whether the action is visible or not when it is in the specified state + * + * \note Passing None will return the current value + * \param state The state to be checked + * \returns Whether the action is visible or not in the specified state + */ + bool isVisible(State state = None) const; + + /** + * Gets whether the action is enabled or not when it is in the specified state + * + * \note Passing None will return the current value + * \param state The state to be checked + * \returns Whether the action is enabled or not in the specified state + */ + bool isEnabled(State state = None) const; + + /** + * \see setTargetPID + */ + qint64 targetPID() const; + + /** + * This method can be used to check the if the current action + * can be performed (i.e. PolKitResult is YES). + * \note This method does not call the authentication dialog, use + * activate() instead + * \return \c true if the action can be performed + */ + bool isAllowed() const; + + /** + * This method compares a PolicyKit action Id with the + * current one of the object. + * + * \see actionId() + * + * \param actionId the action Id to compare + * + * \return \c true if the actionId is the same as this object's one + */ + bool is(const QString &actionId) const; + +private: + class Private; + Private * const d; + + Q_PRIVATE_SLOT(d, void configChanged()) +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(Action::States) + +} + +} + +#endif diff --git a/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbutton.cpp b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbutton.cpp new file mode 100644 index 0000000000..695f6aaa08 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbutton.cpp @@ -0,0 +1,153 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Daniel Nicoletti + SPDX-FileCopyrightText: 2009 Dario Freddi + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "polkitqt1-gui-actionbutton.h" + +#include "polkitqt1-gui-actionbutton_p.h" + +namespace PolkitQt1 +{ + +namespace Gui +{ + +ActionButton::ActionButton(QAbstractButton *button, const QString &actionId, QObject *parent) + : Action(actionId, parent) + , d_ptr(new ActionButtonPrivate(QList() << button)) +{ + d_ptr->q_ptr = this; + + setButton(button); + connect(this, SIGNAL(dataChanged()), SLOT(updateButton())); +} + +ActionButton::ActionButton(ActionButtonPrivate &dd, const QString &actionId, QObject *parent) + : Action(actionId, parent) + , d_ptr(&dd) +{ + d_ptr->q_ptr = this; + + connect(this, SIGNAL(dataChanged()), SLOT(updateButton())); +} + +ActionButton::~ActionButton() +{ + delete d_ptr; +} + +void ActionButtonPrivate::updateButton() +{ + Q_Q(ActionButton); + + Q_FOREACH(QAbstractButton *ent, buttons) { + ent->setVisible(q->isVisible()); + ent->setEnabled(q->isEnabled()); + ent->setText(q->text()); + if (!q->toolTip().isNull()) { + ent->setToolTip(q->toolTip()); + } + if (!q->whatsThis().isNull()) { + ent->setWhatsThis(q->whatsThis()); + } + ent->setIcon(q->icon()); + // if the item cannot do the action anymore + // lets revert to the initial state + if (ent->isCheckable()) { + ent->setChecked(q->isChecked()); + } + } +} + +bool ActionButton::activate() +{ + Q_D(ActionButton); + + bool tg = false; + Q_FOREACH(QAbstractButton *ent, d->buttons) { + if (ent->isCheckable()) { + // we set the current Action state + ent->setChecked(isChecked()); + // toggle the action cause we are not directly connected there.. + tg = true; + } + } + + if (tg) { + toggle(); + } + + return Action::activate(); +} + +void ActionButton::setButton(QAbstractButton *button) +{ + Q_D(ActionButton); + + // First, let's clear the list + Q_FOREACH(QAbstractButton *ent, d->buttons) { + d->removeButton(ent); + } + + // And then add it + d->addButton(button); +} + +void ActionButtonPrivate::addButton(QAbstractButton *button) +{ + Q_Q(ActionButton); + + buttons.append(button); + QObject::connect(button, SIGNAL(clicked(bool)), q, SLOT(streamClicked(bool))); + QObject::connect(q, SIGNAL(toggled(bool)), button, SLOT(toggle())); + if (q->isCheckable()) { + // the button should follow our first buttons + button->setCheckable(true); + } else if (button->isCheckable()) { + // if we are not checkable BUT the button + // is (eg a QCheckBox) we should set all buttons to + // checkable. + Q_FOREACH(QAbstractButton *ent, buttons) { + ent->setCheckable(true); + } + // set the checkable state of Action to store the initial state + q->setCheckable(true); + } + // call this after m_activateOnCheck receives the value + updateButton(); +} + +void ActionButtonPrivate::removeButton(QAbstractButton *button) +{ + Q_Q(ActionButton); + + if (buttons.contains(button)) { + QObject::disconnect(button, SIGNAL(clicked(bool)), q, SLOT(streamClicked(bool))); + QObject::disconnect(q, SIGNAL(toggled(bool)), button, SLOT(toggle())); + buttons.removeOne(button); + } +} + +QAbstractButton *ActionButton::button() const +{ + Q_D(const ActionButton); + + return d->buttons.first(); +} + +void ActionButtonPrivate::streamClicked(bool c) +{ + Q_Q(ActionButton); + + Q_EMIT q->clicked(qobject_cast(q->sender()), c); +} + +} + +} + +#include "moc_polkitqt1-gui-actionbutton.cpp" diff --git a/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbutton.h b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbutton.h new file mode 100644 index 0000000000..8aa01c626f --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbutton.h @@ -0,0 +1,131 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Daniel Nicoletti + SPDX-FileCopyrightText: 2009 Dario Freddi + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef POLKITQT1_GUI_ACTIONBUTTON_H +#define POLKITQT1_GUI_ACTIONBUTTON_H + +#include "polkitqt1-gui-action.h" + +class QAbstractButton; + +namespace PolkitQt1 +{ + +namespace Gui +{ + +class ActionButtonPrivate; +/** + * \class ActionButton polkitqt1-gui-actionbutton.h ActionButton + * \author Daniel Nicoletti + * \author Dario Freddi + * + * \brief Class used to hold and update a QAbstractButton + * + * This class allows you to associate QAbstractButtons + * (i.e. QPushButton) to a PolicyKit Action. It will update the + * button properties according to the PolicyKit Action automatically. + * + * \note You should connect the activated() signal to receive + * a notification when the user clicked the button and gets + * permission to perform the given action. If you set 'noEnabled' + * to \c true it will be emitted when PolKitResult is NO. + */ +class POLKITQT1_GUI_EXPORT ActionButton : public Action +{ + Q_OBJECT + Q_DECLARE_PRIVATE(ActionButton) + Q_DISABLE_COPY(ActionButton) + +public: + /** + * Constructs a new ActionButton. You need to pass this + * constructor an existing QAbstractButton, whose properties + * will be modified according to the underlying Action + * object. As ActionButton inherits from Action, you can + * define your button's behavior right through this wrapper. + * + * \see Action + * + * \param button the QAbstractButton to associate to this ActionButton + * \param actionId the action Id to create the underlying Action + * \param parent the parent object + */ + explicit ActionButton(QAbstractButton *button, const QString &actionId = QString(), QObject *parent = nullptr); + ~ActionButton() override; + + /** + * Sets the button associated to the underlying action. + * + * \note If you are calling this function, you're probably + * changing the button the action is referring to. If this + * is the case, please note that Polkit-Qt does not handle + * the previous button's memory, so you should take care of + * deleting it yourself (if needed). You can retrieve it by + * using button() + * + * \see button + * + * \param button the new button associated with the underlying action + */ + void setButton(QAbstractButton *button); + + /** + * Returns the current button + * + * \return the button currently associated with the underlying action + */ + QAbstractButton *button() const; + +public Q_SLOTS: + /** + * Connect clicked() signals to this slot. This should be + * manually done, as in some cases we might want + * to manually call this. Calling this will emit authorized(). + * + * \note This slot is reentrant which is likely to only be a problem + * if you are creating an interface to setup PolicyKit policies. + * \note If you have a checkbox, connect to its' clicked() signal + * to avoid an infinite loop as this function internally calls setChecked(). + * You can always use the clicked(bool) signal in this class to + * connect to here. + * \warning if you use this class take care to not call Action::activate + * otherwise your checkable buttons won't be properly updated. + */ + bool activate(); + +Q_SIGNALS: + /** + * Emitted when the abstract button clicked(bool) signal + * is emitted. This allows you to use qobject_cast(sender()) + * in a slot connected to this signal and call activate() on it. + * + * \note you will normally want to connect this signal + * to the activate slot. + * + * \param button the button that has been clicked + * \param checked the checked state, if applicable. Otherwise \c false + * + */ + void clicked(QAbstractButton *button, bool checked = false); + +protected: + ActionButton(ActionButtonPrivate &dd, const QString &actionId, QObject *parent = nullptr); + + ActionButtonPrivate * const d_ptr; + +private: + Q_PRIVATE_SLOT(d_func(), void updateButton()) + Q_PRIVATE_SLOT(d_func(), void streamClicked(bool)) +}; + +} + +} + +#endif diff --git a/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbutton_p.h b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbutton_p.h new file mode 100644 index 0000000000..bc87799799 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbutton_p.h @@ -0,0 +1,37 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Dario Freddi + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef POLKITQT1_GUI_ACTIONBUTTON_P_H +#define POLKITQT1_GUI_ACTIONBUTTON_P_H + +#include + +#include +#include + +/** + * \internal + */ +class PolkitQt1::Gui::ActionButtonPrivate +{ +public: + ActionButtonPrivate(const QList &b) + : buttons(b) {} + virtual ~ActionButtonPrivate() {} + + void addButton(QAbstractButton *button); + void removeButton(QAbstractButton *button); + void updateButton(); + void streamClicked(bool); + + Q_DECLARE_PUBLIC(ActionButton) + ActionButton *q_ptr; + + QList buttons; +}; + +#endif /* ACTIONBUTTON_P_H */ diff --git a/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbuttons.cpp b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbuttons.cpp new file mode 100644 index 0000000000..07e0cf134d --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbuttons.cpp @@ -0,0 +1,58 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Dario Freddi + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "polkitqt1-gui-actionbuttons.h" + +#include "polkitqt1-gui-actionbuttons_p.h" + +namespace PolkitQt1 +{ + +namespace Gui +{ + +ActionButtons::ActionButtons(const QList &buttons, const QString &actionId, QObject *parent) + : ActionButton(*new ActionButtonsPrivate(buttons), actionId, parent) +{ + setButtons(buttons); +} + +ActionButtons::~ActionButtons() +{ +} + +void ActionButtons::setButtons(const QList &buttons) +{ + Q_FOREACH(QAbstractButton *ent, buttons) { + addButton(ent); + } +} + +QList ActionButtons::buttons() const +{ + Q_D(const ActionButtons); + + return d->buttons; +} + +void ActionButtons::addButton(QAbstractButton *button) +{ + Q_D(ActionButtons); + + d->addButton(button); +} + +void ActionButtons::removeButton(QAbstractButton *button) +{ + Q_D(ActionButtons); + + d->removeButton(button); +} + +} + +} diff --git a/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbuttons.h b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbuttons.h new file mode 100644 index 0000000000..827e56781c --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbuttons.h @@ -0,0 +1,101 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Dario Freddi + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef POLKITQT1_GUI_ACTIONBUTTONS_H +#define POLKITQT1_GUI_ACTIONBUTTONS_H + +#include "polkitqt1-gui-actionbutton.h" + +namespace PolkitQt1 +{ + +namespace Gui +{ + +class ActionButtonsPrivate; +/** + * \class ActionButtons polkitqt1-gui-actionbuttons.h ActionButtons + * \author Dario Freddi + * + * \brief Class used to hold and update a list of QAbstractButtons + * + * This class is a convenience wrapper around ActionButton that lets + * you associate an undefined number of QAbstractButtons with a single + * action. Every button will be updated accordingly upon action's properties + * changes. + * + * \see ActionButton + */ +class ActionButtons : public ActionButton +{ + Q_OBJECT + Q_DECLARE_PRIVATE(ActionButtons) + Q_DISABLE_COPY(ActionButtons) + +public: + /** + * Constructs a new ActionButton. You need to pass this + * constructor an existing list of QAbstractButtons, whose properties + * will be modified according to the underlying Action + * object. As ActionButtons inherits from Action, you can + * define your buttons' behavior right through this wrapper. + * + * \see Action + * + * \param buttons the QAbstractButton to associate to this ActionButton + * \param actionId the action Id to create the underlying Action + * \param parent the parent object + */ + explicit ActionButtons(const QList &buttons, const QString &actionId = QString(), QObject *parent = nullptr); + ~ActionButtons() override; + + /** + * Sets a list of buttons associated to the underlying action. + * + * \note If you are calling this function, you're probably + * changing the buttons list the action is referring to. If this + * is the case, please note that Polkit-Qt does not handle + * the previous buttons' memory, so you should take care of + * deleting them yourself (if needed). You can retrieve it by + * using buttons() + * + * \see buttons + * + * \param buttons the new buttons associated with the underlying action + */ + void setButtons(const QList &buttons); + + /** + * Returns the current buttons list + * + * \return the buttons currently associated with the underlying action + */ + QList buttons() const; + + /** + * Adds a button to the current button list. The button's properties + * will be updated according to the action upon adding. + * + * \param button the button to add + */ + void addButton(QAbstractButton *button); + + /** + * Removes a button from the current list. Please note that Polkit-Qt + * does not handle the removed button's memory, so you should take care of + * deleting it yourself (if needed). + * + * \param button the button to remove + */ + void removeButton(QAbstractButton *button); +}; + +} + +} + +#endif diff --git a/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbuttons_p.h b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbuttons_p.h new file mode 100644 index 0000000000..7ce780aaf1 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/gui/polkitqt1-gui-actionbuttons_p.h @@ -0,0 +1,23 @@ +/* + This file is part of the Polkit-qt project + SPDX-FileCopyrightText: 2009 Dario Freddi + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef POLKITQT1_GUI_ACTIONBUTTONS_P_H +#define POLKITQT1_GUI_ACTIONBUTTONS_P_H + +#include "polkitqt1-gui-actionbutton_p.h" + +/** + * \internal + */ +class PolkitQt1::Gui::ActionButtonsPrivate : public ActionButtonPrivate +{ +public: + ActionButtonsPrivate(const QList &b) + : ActionButtonPrivate(b) {} +}; + +#endif /* ACTIONBUTTONS_P_H */ diff --git a/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/ActionDescription b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/ActionDescription new file mode 100644 index 0000000000..f6dff44c38 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/ActionDescription @@ -0,0 +1 @@ +#include "../polkitqt1-actiondescription.h" diff --git a/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Agent/Listener b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Agent/Listener new file mode 100644 index 0000000000..3da871e041 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Agent/Listener @@ -0,0 +1 @@ +#include "../../polkitqt1-agent-listener.h" diff --git a/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Agent/Session b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Agent/Session new file mode 100644 index 0000000000..20eb9ffb87 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Agent/Session @@ -0,0 +1 @@ +#include "../../polkitqt1-agent-session.h" diff --git a/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Authority b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Authority new file mode 100644 index 0000000000..523b3c2c07 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Authority @@ -0,0 +1 @@ +#include "../polkitqt1-authority.h" diff --git a/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Details b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Details new file mode 100644 index 0000000000..27da49aa10 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Details @@ -0,0 +1 @@ +#include "../polkitqt1-details.h" diff --git a/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Gui/Action b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Gui/Action new file mode 100644 index 0000000000..210911de2b --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Gui/Action @@ -0,0 +1 @@ +#include "../../polkitqt1-gui-action.h" diff --git a/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Gui/ActionButton b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Gui/ActionButton new file mode 100644 index 0000000000..2076f277ee --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Gui/ActionButton @@ -0,0 +1 @@ +#include "../../polkitqt1-gui-actionbutton.h" diff --git a/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Gui/ActionButtons b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Gui/ActionButtons new file mode 100644 index 0000000000..555098f774 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Gui/ActionButtons @@ -0,0 +1 @@ +#include "../../polkitqt1-gui-actionbuttons.h" diff --git a/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Identity b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Identity new file mode 100644 index 0000000000..999f5ae889 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Identity @@ -0,0 +1 @@ +#include "../polkitqt1-identity.h" diff --git a/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Subject b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Subject new file mode 100644 index 0000000000..919a66f52e --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/Subject @@ -0,0 +1 @@ +#include "../polkitqt1-subject.h" diff --git a/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/TemporaryAuthorization b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/TemporaryAuthorization new file mode 100644 index 0000000000..b676a19e5b --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/includes/PolkitQt1/TemporaryAuthorization @@ -0,0 +1 @@ +#include "../polkitqt1-temporaryauthorization.h" diff --git a/local/recipes/libs/polkit-qt6/source/metainfo.yaml b/local/recipes/libs/polkit-qt6/source/metainfo.yaml new file mode 100644 index 0000000000..9586a6cfe6 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/metainfo.yaml @@ -0,0 +1,21 @@ +fancyname: PolkitQt-1 +description: Qt wrapper around polkit-1 +platforms: + - name: Linux +# - name: FreeBSD +# - name: Windows +# - name: MacOSX +# - name: Android +release: true +public_lib: true +public_source_dirs: + - core + - gui + - agent +libraries: + - cmake: "PolkitQt5-1::Core" + - cmake: "PolkitQt5-1::Gui" + - cmake: "PolkitQt5-1::Agent" +cmakename: PolkitQt-1 +irc: kde-devel +mailinglist: kde-core-devel diff --git a/local/recipes/libs/polkit-qt6/source/polkit-qt-1.pc.cmake b/local/recipes/libs/polkit-qt6/source/polkit-qt-1.pc.cmake new file mode 100644 index 0000000000..ba8e46e4fe --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/polkit-qt-1.pc.cmake @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@POLKITQT-1_INCLUDE_PATH@ + +Name: @POLKITQT-1_PCNAME@ +Description: Convenience library for using polkit with a Qt-styled API +Version: @POLKITQT-1_VERSION_STRING@ +Requires: @POLKITQT-1_CORE_PCNAME@ @POLKITQT-1_GUI_PCNAME@ @POLKITQT-1_AGENT_PCNAME@ +Libs: -L${libdir} -l@POLKITQT-1_CORE_PCNAME@ -l@POLKITQT-1_GUI_PCNAME@ -l@POLKITQT-1_AGENT_PCNAME@ +Cflags: -I${includedir} diff --git a/local/recipes/libs/polkit-qt6/source/polkit-qt-agent-1.pc.cmake b/local/recipes/libs/polkit-qt6/source/polkit-qt-agent-1.pc.cmake new file mode 100644 index 0000000000..23b2caef64 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/polkit-qt-agent-1.pc.cmake @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@POLKITQT-1_INCLUDE_PATH@ + +Name: @POLKITQT-1_AGENT_PCNAME@ +Description: Convenience library for using polkit Agent with a Qt-styled API +Version: @POLKITQT-1_VERSION_STRING@ +Requires: QtCore QtGui +Libs: -L${libdir} -l@POLKITQT-1_AGENT_PCNAME@ +Cflags: -I${includedir} diff --git a/local/recipes/libs/polkit-qt6/source/polkit-qt-core-1.pc.cmake b/local/recipes/libs/polkit-qt6/source/polkit-qt-core-1.pc.cmake new file mode 100644 index 0000000000..fa501f0fbf --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/polkit-qt-core-1.pc.cmake @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@POLKITQT-1_INCLUDE_PATH@ + +Name: @POLKITQT-1_CORE_PCNAME@ +Description: Convenience library for using polkit with a Qt-styled API, non-GUI classes +Version: @POLKITQT-1_VERSION_STRING@ +Requires: QtCore +Libs: -L${libdir} -l@POLKITQT-1_CORE_PCNAME@ +Cflags: -I${includedir} diff --git a/local/recipes/libs/polkit-qt6/source/polkit-qt-gui-1.pc.cmake b/local/recipes/libs/polkit-qt6/source/polkit-qt-gui-1.pc.cmake new file mode 100644 index 0000000000..7261b0ca62 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/polkit-qt-gui-1.pc.cmake @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@POLKITQT-1_INCLUDE_PATH@ + +Name: @POLKITQT-1_GUI_PCNAME@ +Description: Convenience library for using polkit with a Qt-styled API, GUI classes +Version: @POLKITQT-1_VERSION_STRING@ +Requires: QtCore QtGui @POLKITQT-1_CORE_PCNAME@ +Libs: -L${libdir} -l@POLKITQT-1_GUI_PCNAME@ +Cflags: -I${includedir} diff --git a/local/recipes/libs/polkit-qt6/source/polkit-qt5-1.pc.cmake b/local/recipes/libs/polkit-qt6/source/polkit-qt5-1.pc.cmake new file mode 100644 index 0000000000..ba8e46e4fe --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/polkit-qt5-1.pc.cmake @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@POLKITQT-1_INCLUDE_PATH@ + +Name: @POLKITQT-1_PCNAME@ +Description: Convenience library for using polkit with a Qt-styled API +Version: @POLKITQT-1_VERSION_STRING@ +Requires: @POLKITQT-1_CORE_PCNAME@ @POLKITQT-1_GUI_PCNAME@ @POLKITQT-1_AGENT_PCNAME@ +Libs: -L${libdir} -l@POLKITQT-1_CORE_PCNAME@ -l@POLKITQT-1_GUI_PCNAME@ -l@POLKITQT-1_AGENT_PCNAME@ +Cflags: -I${includedir} diff --git a/local/recipes/libs/polkit-qt6/source/polkit-qt5-agent-1.pc.cmake b/local/recipes/libs/polkit-qt6/source/polkit-qt5-agent-1.pc.cmake new file mode 100644 index 0000000000..60b22d5019 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/polkit-qt5-agent-1.pc.cmake @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@POLKITQT-1_INCLUDE_PATH@ + +Name: @POLKITQT-1_AGENT_PCNAME@ +Description: Convenience library for using polkit Agent with a Qt-styled API +Version: @POLKITQT-1_VERSION_STRING@ +Requires: Qt@QT_MAJOR_VERSION@Core Qt@QT_MAJOR_VERSION@Gui +Libs: -L${libdir} -l@POLKITQT-1_AGENT_PCNAME@ +Cflags: -I${includedir} diff --git a/local/recipes/libs/polkit-qt6/source/polkit-qt5-core-1.pc.cmake b/local/recipes/libs/polkit-qt6/source/polkit-qt5-core-1.pc.cmake new file mode 100644 index 0000000000..2f5d56257a --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/polkit-qt5-core-1.pc.cmake @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@POLKITQT-1_INCLUDE_PATH@ + +Name: @POLKITQT-1_CORE_PCNAME@ +Description: Convenience library for using polkit with a Qt-styled API, non-GUI classes +Version: @POLKITQT-1_VERSION_STRING@ +Requires: Qt@QT_MAJOR_VERSION@Core +Libs: -L${libdir} -l@POLKITQT-1_CORE_PCNAME@ +Cflags: -I${includedir} diff --git a/local/recipes/libs/polkit-qt6/source/polkit-qt5-gui-1.pc.cmake b/local/recipes/libs/polkit-qt6/source/polkit-qt5-gui-1.pc.cmake new file mode 100644 index 0000000000..1d208fb737 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/polkit-qt5-gui-1.pc.cmake @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@POLKITQT-1_INCLUDE_PATH@ + +Name: @POLKITQT-1_GUI_PCNAME@ +Description: Convenience library for using polkit with a Qt-styled API, GUI classes +Version: @POLKITQT-1_VERSION_STRING@ +Requires: Qt@QT_MAJOR_VERSION@Core Qt@QT_MAJOR_VERSION@Gui @POLKITQT-1_CORE_PCNAME@ +Libs: -L${libdir} -l@POLKITQT-1_GUI_PCNAME@ +Cflags: -I${includedir} diff --git a/local/recipes/libs/polkit-qt6/source/polkit-qt6-1.pc.cmake b/local/recipes/libs/polkit-qt6/source/polkit-qt6-1.pc.cmake new file mode 100644 index 0000000000..ba8e46e4fe --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/polkit-qt6-1.pc.cmake @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@POLKITQT-1_INCLUDE_PATH@ + +Name: @POLKITQT-1_PCNAME@ +Description: Convenience library for using polkit with a Qt-styled API +Version: @POLKITQT-1_VERSION_STRING@ +Requires: @POLKITQT-1_CORE_PCNAME@ @POLKITQT-1_GUI_PCNAME@ @POLKITQT-1_AGENT_PCNAME@ +Libs: -L${libdir} -l@POLKITQT-1_CORE_PCNAME@ -l@POLKITQT-1_GUI_PCNAME@ -l@POLKITQT-1_AGENT_PCNAME@ +Cflags: -I${includedir} diff --git a/local/recipes/libs/polkit-qt6/source/polkit-qt6-agent-1.pc.cmake b/local/recipes/libs/polkit-qt6/source/polkit-qt6-agent-1.pc.cmake new file mode 100644 index 0000000000..60b22d5019 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/polkit-qt6-agent-1.pc.cmake @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@POLKITQT-1_INCLUDE_PATH@ + +Name: @POLKITQT-1_AGENT_PCNAME@ +Description: Convenience library for using polkit Agent with a Qt-styled API +Version: @POLKITQT-1_VERSION_STRING@ +Requires: Qt@QT_MAJOR_VERSION@Core Qt@QT_MAJOR_VERSION@Gui +Libs: -L${libdir} -l@POLKITQT-1_AGENT_PCNAME@ +Cflags: -I${includedir} diff --git a/local/recipes/libs/polkit-qt6/source/polkit-qt6-core-1.pc.cmake b/local/recipes/libs/polkit-qt6/source/polkit-qt6-core-1.pc.cmake new file mode 100644 index 0000000000..2f5d56257a --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/polkit-qt6-core-1.pc.cmake @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@POLKITQT-1_INCLUDE_PATH@ + +Name: @POLKITQT-1_CORE_PCNAME@ +Description: Convenience library for using polkit with a Qt-styled API, non-GUI classes +Version: @POLKITQT-1_VERSION_STRING@ +Requires: Qt@QT_MAJOR_VERSION@Core +Libs: -L${libdir} -l@POLKITQT-1_CORE_PCNAME@ +Cflags: -I${includedir} diff --git a/local/recipes/libs/polkit-qt6/source/polkit-qt6-gui-1.pc.cmake b/local/recipes/libs/polkit-qt6/source/polkit-qt6-gui-1.pc.cmake new file mode 100644 index 0000000000..1d208fb737 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/polkit-qt6-gui-1.pc.cmake @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@POLKITQT-1_INCLUDE_PATH@ + +Name: @POLKITQT-1_GUI_PCNAME@ +Description: Convenience library for using polkit with a Qt-styled API, GUI classes +Version: @POLKITQT-1_VERSION_STRING@ +Requires: Qt@QT_MAJOR_VERSION@Core Qt@QT_MAJOR_VERSION@Gui @POLKITQT-1_CORE_PCNAME@ +Libs: -L${libdir} -l@POLKITQT-1_GUI_PCNAME@ +Cflags: -I${includedir} diff --git a/local/recipes/libs/polkit-qt6/source/polkitqt1-config.h.cmake b/local/recipes/libs/polkit-qt6/source/polkitqt1-config.h.cmake new file mode 100644 index 0000000000..fed40a9696 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/polkitqt1-config.h.cmake @@ -0,0 +1 @@ +#cmakedefine01 HAVE_POLKIT_SYSTEM_BUS_NAME_GET_USER_SYNC diff --git a/local/recipes/libs/polkit-qt6/source/polkitqt1-version.h.cmake b/local/recipes/libs/polkit-qt6/source/polkitqt1-version.h.cmake new file mode 100644 index 0000000000..e8a3e76905 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/polkitqt1-version.h.cmake @@ -0,0 +1,53 @@ +/* + SPDX-FileCopyrightText: 2007 Sebastian Trueg + SPDX-FileCopyrightText: 2009 Dario Freddi + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef _POLKITQT1_VERSION_H_ +#define _POLKITQT1_VERSION_H_ + +/// @brief PolkitQt-1 version as string at compile time. +#define POLKITQT1_VERSION_STRING "${POLKITQT-1_VERSION_STRING}" + +/// @brief The major PolkitQt-1 version number at compile time +#define POLKITQT1_VERSION_MAJOR ${POLKITQT-1_VERSION_MAJOR} + +/// @brief The minor PolkitQt-1 version number at compile time +#define POLKITQT1_VERSION_MINOR ${POLKITQT-1_VERSION_MINOR} + +/// @brief The PolkitQt-1 patch version number at compile time +#define POLKITQT1_VERSION_PATCH ${POLKITQT-1_VERSION_PATCH} + +/** + * \brief Create a unique number from the major, minor and release number of a %PolkitQt-1 version + * + * This function can be used for preprocessing. + */ +#define POLKITQT1_MAKE_VERSION( a,b,c ) (((a) << 16) | ((b) << 8) | (c)) + +/** + * \brief %PolkitQt-1 Version as a unique number at compile time + * + * This macro calculates the %PolkitQt-1 version into a number. It is mainly used + * through POLKITQT1_IS_VERSION in preprocessing. + */ +#define POLKITQT1_VERSION \ + POLKITQT1_MAKE_VERSION(POLKITQT1_VERSION_MAJOR,POLKITQT1_VERSION_MINOR,POLKITQT1_VERSION_PATCH) + +/** + * \brief Check if the %PolkitQt-1 version matches a certain version or is higher + * + * This macro is typically used to compile conditionally a part of code: + * \code + * #if POLKITQT1_IS_VERSION(2,1) + * // Code for PolkitQt-1 2.1 + * #else + * // Code for PolkitQt-1 2.0 + * #endif + * \endcode + */ +#define POLKITQT1_IS_VERSION(a,b,c) ( POLKITQT1_VERSION >= POLKITQT1_MAKE_VERSION(a,b,c) ) + +#endif diff --git a/local/recipes/libs/polkit-qt6/source/test/CMakeLists.txt b/local/recipes/libs/polkit-qt6/source/test/CMakeLists.txt new file mode 100644 index 0000000000..d587034452 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/test/CMakeLists.txt @@ -0,0 +1,16 @@ +enable_testing() + +add_executable(polkit-qt-test + test.cpp +) + +target_link_libraries(polkit-qt-test + Qt${QT_MAJOR_VERSION}::Core + Qt${QT_MAJOR_VERSION}::DBus + Qt${QT_MAJOR_VERSION}::Test + Qt${QT_MAJOR_VERSION}::Widgets + ${POLKITQT-1_CORE_PCNAME} + ${POLKITQT-1_AGENT_PCNAME} +) + +add_test(BaseTest ${CMAKE_CURRENT_BINARY_DIR}/polkit-qt-test) diff --git a/local/recipes/libs/polkit-qt6/source/test/test.cpp b/local/recipes/libs/polkit-qt6/source/test/test.cpp new file mode 100644 index 0000000000..fb2f702b93 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/test/test.cpp @@ -0,0 +1,237 @@ + + +#include "test.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace PolkitQt1; +using namespace PolkitQt1::Agent; + +void wait() +{ + for (int i = 0; i < 100; i++) { + usleep(100); + QCoreApplication::processEvents(); + } +} + +void TestAuth::test_Auth_checkAuthorization() +{ + // This needs the file org.qt.policykit.examples.policy from examples to be installed + UnixProcessSubject process(QCoreApplication::applicationPid()); + Authority::Result result; + // Check if this method returns good authorization results + Authority *authority = Authority::instance(); + result = authority->checkAuthorizationSync("org.qt.policykit.examples.kick", process, Authority::None); + QCOMPARE(result, Authority::No); + QVERIFY(!authority->hasError()); + result = authority->checkAuthorizationSync("org.qt.policykit.examples.cry", process, Authority::None); + QCOMPARE(result, Authority::Yes); + QVERIFY(!authority->hasError()); + result = authority->checkAuthorizationSync("org.qt.policykit.examples.bleed", process, Authority::None); + QCOMPARE(result, Authority::Challenge); + QVERIFY(!authority->hasError()); + + // Now we try async methods + QSignalSpy spy(authority, SIGNAL(checkAuthorizationFinished(PolkitQt1::Authority::Result))); + // Call asynchronous checkAuthorization + authority->checkAuthorization("org.qt.policykit.examples.kick", process, Authority::None); + // Give the polkit time to obtain the result and emit the signal with it + wait(); + // Test if the signal was emitted + QCOMPARE(spy.count(), 1); + // Test the result + result = spy.takeFirst()[0].value(); + QCOMPARE(result, Authority::No); + QVERIFY(!authority->hasError()); + spy.clear(); + + // Let's test the cancellability + authority->checkAuthorization("org.qt.policykit.examples.kick", process, Authority::None); + authority->checkAuthorizationCancel(); + // Wait and check if the signal arrieved + wait(); + QCOMPARE(spy.count(), 0); + + // Check if it can cancel user authentication dialog + authority->checkAuthorization("org.qt.policykit.examples.bleed", process, Authority::AllowUserInteraction); + // Show it for second + sleep(1); + // And now kill it + authority->checkAuthorizationCancel(); + QVERIFY(!authority->hasError()); + // But how to test if it was successful? + qWarning() << "You should see an authentication dialog for a short period."; +} + +void TestAuth::test_Auth_enumerateActions() +{ + // This needs the file org.qt.policykit.examples.policy from examples to be installed + ActionDescription::List list = Authority::instance()->enumerateActionsSync(); + QVERIFY(!Authority::instance()->hasError()); + // Check whether enumerateAction returns at least example actions + int count = 0; + Q_FOREACH(const ActionDescription &ad, list) { + if ((ad.actionId() == "org.qt.policykit.examples.kick") || + (ad.actionId() == "org.qt.policykit.examples.cry") || + (ad.actionId() == "org.qt.policykit.examples.bleed")) + count++; + } + QCOMPARE(count, 3); + + + // Test asynchronous version as well + list.clear(); + count = 0; + QSignalSpy spy(Authority::instance(), SIGNAL(enumerateActionsFinished(PolkitQt1::ActionDescription::List))); + Authority::instance()->enumerateActions(); + wait(); + QCOMPARE(spy.count(), 1); + list = spy.takeFirst()[0].value(); + QVERIFY(!Authority::instance()->hasError()); + Q_FOREACH(const ActionDescription &ad, list) { + if ((ad.actionId() == "org.qt.policykit.examples.kick") || + (ad.actionId() == "org.qt.policykit.examples.cry") || + (ad.actionId() == "org.qt.policykit.examples.bleed")) + count++; + } + QCOMPARE(count, 3); + + // Test cancelling the enumeration + spy.clear(); + Authority::instance()->enumerateActions(); + Authority::instance()->enumerateActionsCancel(); + wait(); + QCOMPARE(spy.count(), 0); + QVERIFY(!Authority::instance()->hasError()); +} + +void TestAuth::test_Identity() +{ + // Get real name and id of current user and group + struct passwd *userinfo = getpwuid(getuid()); + QString userName = userinfo->pw_name; + unsigned int userId = userinfo->pw_uid; + unsigned int groupId = userinfo->pw_gid; + + // Try to create UnixUser from username + UnixUserIdentity user(userName); + QVERIFY(user.identity()); + + // Create generic Identity from UnixUser via string representation + Identity id = Identity::fromString(user.toString()); + // Compare obtained uid with real uid + QCOMPARE(id.toUnixUserIdentity().uid(), userId); + + // Create generic Identity from UnixGroup via string representation + UnixGroupIdentity group(groupId); + QVERIFY(group.identity()); + id = Identity::fromString(group.toString()); + QCOMPARE(id.toUnixGroupIdentity().gid(), groupId); + + // Test setting gid to another value + group.setGid(9999U); + id = Identity::fromString(group.toString()); + QCOMPARE(id.toUnixGroupIdentity().gid(), 9999U); +} + +void TestAuth::test_Authority() +{ + Authority *authority = Authority::instance(); + QVERIFY(authority); + QVERIFY(!authority->hasError()); + + // Verify emitting of the signals + QSignalSpy spy(authority, SIGNAL(consoleKitDBChanged())); + QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + "org.freedesktop.ConsoleKit.Manager", + "OpenSession"); + QDBusMessage reply = QDBusConnection::systemBus().call(msg); + QString cookie; + cookie = reply.arguments()[0].value(); + + + msg = QDBusMessage::createMethodCall("org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + "org.freedesktop.ConsoleKit.Manager", + "CloseSession"); + msg.setArguments(QList () << cookie); + QDBusConnection::systemBus().call(msg); + // FIXME: Emitting consoleKitDBChanged is not working now + qWarning() << "Emitting consoleKitDBChanged is not working now, test will be skipped"; + //QVERIFY(spy.count() > 0); + QVERIFY(!authority->hasError()); + + // configChanged signal from authority requires changing some policy files + // and it would require user interaction (typing the password) + // so this is not covered by this test +} + +void TestAuth::test_Subject() +{ + // Get pid of this application + qint64 pid = QCoreApplication::applicationPid(); + // Create unix process for it + UnixProcessSubject *process = new UnixProcessSubject(pid); + // Test if pid doesn't differ + QCOMPARE(process->pid(), pid); + + // Serialize and deserialize subject + //Subject *subject = Subject::fromString(process->toString()); + // and try it + //QCOMPARE(((UnixProcess *) subject)->pid(), pid); + delete process; +} + +void TestAuth::test_Session() +{ + /* + UnixUser user(getuid()); + Session *session = new Session(&user, "/org/freedesktop/ConsoleKit/Session2"); + QSignalSpy spy_completed(session, SIGNAL(completed(bool))); + QSignalSpy spy_request(session, SIGNAL(request(QString,bool))); + QSignalSpy spy_error(session, SIGNAL(showError(QString))); + QSignalSpy spy_info(session, SIGNAL(showInfo(QString))); + session->initiate(); + session->response("aaa"); + // Canceling should emit the "completed" signal + session->cancel(); + QCOMPARE(spy_completed.count(), 1); + + //UnixProcess *process = new UnixProcess(QCoreApplication::applicationPid()); + //Authority::instance()->checkAuthorization("org.qt.policykit.examples.kick", process, Authority::None); + + qDebug() << "COMPLETED:" << spy_completed.count(); + qDebug() << "REQUEST:" << spy_request.count(); + qDebug() << "ERROR:" << spy_error.count(); + qDebug() << "INFO:" << spy_info.count(); + */ +} + +void TestAuth::test_Details() +{ + Details details; + details.insert("1", "aaa"); + details.insert("2", "bbb"); + details.insert("3", "ccc"); + details.insert("4", "ddd"); + QCOMPARE(details.lookup("1"), QString("aaa")); + QCOMPARE(details.lookup("2"), QString("bbb")); + QCOMPARE(details.lookup("3"), QString("ccc")); + QCOMPARE(details.lookup("4"), QString("ddd")); + QList list = details.keys(); + QVERIFY(list.contains("1")); + QVERIFY(list.contains("2")); + QVERIFY(list.contains("3")); + QVERIFY(list.contains("4")); +} + +QTEST_MAIN(TestAuth) diff --git a/local/recipes/libs/polkit-qt6/source/test/test.h b/local/recipes/libs/polkit-qt6/source/test/test.h new file mode 100644 index 0000000000..9dffd18700 --- /dev/null +++ b/local/recipes/libs/polkit-qt6/source/test/test.h @@ -0,0 +1,20 @@ +#ifndef TEST_H +#define TEST_H + +#include +#include + +class TestAuth : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void test_Auth_checkAuthorization(); + void test_Auth_enumerateActions(); + void test_Identity(); + void test_Authority(); + void test_Subject(); + void test_Session(); + void test_Details(); +}; + +#endif // TEST_H