polkit-qt6: vendor as full-fork recipe (path=source, patches baked)
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,2 @@
|
||||
Options:
|
||||
cmake-options: '-DBUILD_EXAMPLES=ON'
|
||||
@@ -0,0 +1 @@
|
||||
polkit-qt-1.git
|
||||
@@ -0,0 +1,9 @@
|
||||
Main Authors:
|
||||
- Daniel Nicoletti <dantti85-dev@yahoo.com.br>
|
||||
- Dario Freddi <drf@kde.org>
|
||||
- Jaroslav Reznik <jreznik@redhat.com>
|
||||
|
||||
Contributors:
|
||||
- Pino Toscano <pino@kde.org>
|
||||
- Lukas Tinkl <ltinkl@redhat.com>
|
||||
- Radek Novacek <rnovacek@redhat.com>
|
||||
@@ -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 <package>Config.cmake files to lib/cmake/<package> instead of lib/<package>/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)
|
||||
@@ -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=<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 :)
|
||||
@@ -0,0 +1,26 @@
|
||||
Copyright (c) <year> <owner>. 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.
|
||||
@@ -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
|
||||
@@ -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!
|
||||
@@ -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 <a href="classes.html">Alphabetical Class List</a>
|
||||
\li <a href="hierarchy.html">Class Hierarchy</a>
|
||||
|
||||
|
||||
|
||||
|
||||
\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<QAbstractButton*>() << 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
|
||||
@@ -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)
|
||||
###########################################
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${POLKITQT-1_INCLUDE_PATH}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
|
||||
)
|
||||
|
||||
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)
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "listeneradapter_p.h"
|
||||
#include <QDebug>
|
||||
#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE 1
|
||||
#include <polkitagent/polkitagent.h>
|
||||
|
||||
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<guint, PolkitQt1::Identity> uniqueIdentities;
|
||||
for (GList *entry = g_list_first(identities); entry != nullptr; entry = g_list_next(entry)) {
|
||||
auto identity = static_cast<PolkitIdentity *>(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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef LISTENER_ADAPTER_P_H
|
||||
#define LISTENER_ADAPTER_P_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#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<Listener *> m_listeners;
|
||||
|
||||
friend class Listener;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "polkitqt1-agent-listener.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef POLKITQT1_AGENT_LISTENER_H
|
||||
#define POLKITQT1_AGENT_LISTENER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QScopedPointer>
|
||||
|
||||
#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 <jreznik@redhat.com>
|
||||
*
|
||||
* \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<ListenerPrivate> d;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
This file is part of the PolKit1-qt project
|
||||
SPDX-FileCopyrightText: 2009 Radek Novacek <rnovacek@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "polkitqt1-agent-session.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "polkitqt1-identity.h"
|
||||
|
||||
#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE 1
|
||||
#include <polkitagent/polkitagent.h>
|
||||
|
||||
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());
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
This file is part of the PolKit1-qt project
|
||||
SPDX-FileCopyrightText: 2009 Radek Novacek <rnovacek@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef POLKITQT1_AGENT_SESSION_H
|
||||
#define POLKITQT1_AGENT_SESSION_H
|
||||
|
||||
#include <QObject>
|
||||
#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 <rnovacek@redhat.com>
|
||||
*
|
||||
* 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
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
|
||||
SPDX-FileContributor: based on code by David Zeuthen <davidz@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
|
||||
#include "polkitqtlistener_p.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
|
||||
SPDX-FileContributor: based on code by David Zeuthen <davidz@redhat.com>
|
||||
|
||||
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 <polkitagent/polkitagent.h>
|
||||
|
||||
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 */
|
||||
@@ -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_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${POLKITQT-1_INCLUDE_PATH}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
|
||||
SPDX-FileCopyrightText: 2010 Dario Freddi <drf@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "polkitqt1-actiondescription.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <polkit/polkit.h>
|
||||
|
||||
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<ActionDescription::ImplicitAuthorization>(polkit_action_description_get_implicit_any(
|
||||
polkitActionDescription));
|
||||
d->implicitInactive = static_cast<ActionDescription::ImplicitAuthorization>(polkit_action_description_get_implicit_inactive(
|
||||
polkitActionDescription));
|
||||
d->implicitActive = static_cast<ActionDescription::ImplicitAuthorization>(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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
|
||||
SPDX-FileCopyrightText: 2010 Dario Freddi <drf@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef POLKITQT1_ACTION_DESCRIPTION_H
|
||||
#define POLKITQT1_ACTION_DESCRIPTION_H
|
||||
|
||||
#include "polkitqt1-core-export.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QMetaType>
|
||||
#include <QSharedData>
|
||||
|
||||
typedef struct _PolkitActionDescription PolkitActionDescription;
|
||||
|
||||
namespace PolkitQt1
|
||||
{
|
||||
/**
|
||||
* \class ActionDescription polkitqt1-actiondescription.h ActionDescription
|
||||
* \author Jaroslav Reznik <jreznik@redhat.com>
|
||||
* \author Dario Freddi <drf@kde.org>
|
||||
*
|
||||
* \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
|
||||
@@ -0,0 +1,902 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Daniel Nicoletti <dantti85-pk@yahoo.com.br>
|
||||
SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
|
||||
SPDX-FileCopyrightText: 2009 Radek Novacek <rnovacek@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "polkitqt1-authority.h"
|
||||
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusReply>
|
||||
|
||||
#include <polkit/polkit.h>
|
||||
|
||||
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<PolkitActionDescription *>(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<PolkitQt1::Authority::Result> ();
|
||||
qRegisterMetaType<PolkitQt1::ActionDescription::List>();
|
||||
|
||||
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<QDBusArgument>()) {
|
||||
arg.value<QDBusArgument>() >> 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<QDBusObjectPath>().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"
|
||||
@@ -0,0 +1,550 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Daniel Nicoletti <dantti85-pk@yahoo.com.br>
|
||||
SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
|
||||
SPDX-FileCopyrightText: 2009 Radek Novacek <rnovacek@redhat.com>
|
||||
|
||||
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 <QObject>
|
||||
#include <QMetaType>
|
||||
#include <QStringList>
|
||||
|
||||
typedef struct _PolkitAuthority PolkitAuthority;
|
||||
|
||||
/**
|
||||
* \namespace PolkitQt1 PolkitQt
|
||||
*
|
||||
* \brief Namespace wrapping Polkit-Qt classes
|
||||
*
|
||||
* This namespace wraps all Polkit-Qt classes.
|
||||
*/
|
||||
namespace PolkitQt1
|
||||
{
|
||||
|
||||
typedef QMap<QString, QString> DetailsMap;
|
||||
|
||||
/**
|
||||
* \class Authority polkitqt1-authority.h Authority
|
||||
* \author Daniel Nicoletti <dantti85-pk@yahoo.com.br>
|
||||
* \author Dario Freddi <drf@kde.org>
|
||||
* \author Jaroslav Reznik <jreznik@redhat.com>
|
||||
*
|
||||
* \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
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Radek Novacek <rnovacek@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "polkitqt1-details.h"
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
#include <polkit/polkit.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Radek Novacek <rnovacek@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef POLKITQT1_DETAILS_H
|
||||
#define POLKITQT1_DETAILS_H
|
||||
|
||||
#include "polkitqt1-core-export.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QSharedData>
|
||||
|
||||
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 <rnovacek@redhat.com>
|
||||
*
|
||||
* \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
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Lukas Tinkl <ltinkl@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "polkitqt1-identity.h"
|
||||
|
||||
#include <polkit/polkit.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Lukas Tinkl <ltinkl@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef POLKITQT1_IDENTITY_H
|
||||
#define POLKITQT1_IDENTITY_H
|
||||
|
||||
#include "polkitqt1-core-export.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QSharedData>
|
||||
|
||||
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 <ltinkl@redhat.com>
|
||||
*
|
||||
* 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
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "polkitqt1-subject.h"
|
||||
#include "polkitqt1-identity.h"
|
||||
#include "polkitqt1-config.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <polkit/polkit.h>
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
This file is part of the PolKit1-qt project
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef POLKITQT1_SUBJECT_H
|
||||
#define POLKITQT1_SUBJECT_H
|
||||
|
||||
#include "polkitqt1-core-export.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QSharedData>
|
||||
|
||||
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 <jreznik@redhat.com>
|
||||
*
|
||||
* \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 <jreznik@redhat.com>
|
||||
*
|
||||
* \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 <jreznik@redhat.com>
|
||||
*
|
||||
* \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 <jreznik@redhat.com>
|
||||
*
|
||||
* \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
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
This file is part of the PolKit1-qt project
|
||||
SPDX-FileCopyrightText: 2009 Radek Novacek <rnovacek@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "polkitqt1-temporaryauthorization.h"
|
||||
#include "polkitqt1-authority.h"
|
||||
|
||||
#include <polkit/polkit.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
This file is part of the PolKit1-qt project
|
||||
SPDX-FileCopyrightText: 2009 Radek Novacek <rnovacek@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef POLKITQT1_TEMPORARYAUTHORIZATION_H
|
||||
#define POLKITQT1_TEMPORARYAUTHORIZATION_H
|
||||
|
||||
#include "polkitqt1-subject.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QDateTime>
|
||||
#include <QMetaType>
|
||||
#include <QSharedData>
|
||||
|
||||
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 <rnovacek@redhat.com>
|
||||
*
|
||||
* \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
|
||||
@@ -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)
|
||||
@@ -0,0 +1,227 @@
|
||||
// This is an example not a library
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2009 Radek Novacek <rnovacek@redhat.com>
|
||||
SPDX-FileCopyrightText: 2008 Daniel Nicoletti <dantti85-pk@yahoo.com.br>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "PkExample.h"
|
||||
|
||||
#include <polkitqt1-gui-actionbutton.h>
|
||||
#include <polkitqt1-gui-actionbuttons.h>
|
||||
#include <polkitqt1-authority.h>
|
||||
#include <QDebug>
|
||||
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusConnection>
|
||||
|
||||
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<Action *>(bt));
|
||||
toolBar->addAction(qobject_cast<Action *>(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<Action *>(bt));
|
||||
toolBar->addAction(qobject_cast<Action *>(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<Action *>(bt));
|
||||
toolBar->addAction(qobject_cast<Action *>(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<Action *>(bt));
|
||||
toolBar->addAction(qobject_cast<Action *>(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<Action *>(bt));
|
||||
toolBar->addAction(qobject_cast<Action *>(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<Action *>(bt));
|
||||
toolBar->addAction(qobject_cast<Action *>(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<Action *>(bt));
|
||||
toolBar->addAction(qobject_cast<Action *>(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<Action *>(bt));
|
||||
toolBar->addAction(qobject_cast<Action *>(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<Action *>(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<Action *>(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<QVariant> 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<uint>(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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// This is an example not a library
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2008 Daniel Nicoletti <dantti85-pk@yahoo.com.br>
|
||||
SPDX-FileCopyrightText: 2009 Radek Novacek <rnovacek@redhat.com>
|
||||
|
||||
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
|
||||
@@ -0,0 +1,234 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PkExample</class>
|
||||
<widget class="QMainWindow" name="PkExample">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>PolicyKit-qt example</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="3,1">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="kickL">
|
||||
<property name="text">
|
||||
<string>Making the helper <b>Kick</b> is not allowed. Action cannot be triggered.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="kickPB">
|
||||
<property name="text">
|
||||
<string>Kick!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="cryL">
|
||||
<property name="text">
|
||||
<string><!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></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="cryPB">
|
||||
<property name="text">
|
||||
<string>Cry!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="bleedL">
|
||||
<property name="text">
|
||||
<string>Making the helper <b>Bleed</b> requires the user to authenticate. This is a one-shot authorization.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="bleedPB">
|
||||
<property name="text">
|
||||
<string>Bleed!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="playL">
|
||||
<property name="text">
|
||||
<string>Making the helper <b>Play</b> requires a system administrator to authenticate. This is a one-shot authorization.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QPushButton" name="playPB">
|
||||
<property name="text">
|
||||
<string>Play!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="listenL">
|
||||
<property name="text">
|
||||
<string>Making the helper <b>Listen</b> requires the user to authenticate. The authorization will be kept for a brief period.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QPushButton" name="listenPB">
|
||||
<property name="text">
|
||||
<string>Listen!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="deleteL">
|
||||
<property name="text">
|
||||
<string>Making the helper <b>Delete</b> requires a system administrator to authenticate. The authorization will be kept for a brief period.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QPushButton" name="deletePB">
|
||||
<property name="text">
|
||||
<string>Delete!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" rowspan="2">
|
||||
<widget class="QLabel" name="deleteL_2">
|
||||
<property name="text">
|
||||
<string><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.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="setCB">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>no</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>yes</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>auth_self</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>auth_admin</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>auth_self_keep</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>auth_admin_keep</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QPushButton" name="setPB">
|
||||
<property name="text">
|
||||
<string>Set!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="deleteL_3">
|
||||
<property name="text">
|
||||
<string>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.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QPushButton" name="shoutPB">
|
||||
<property name="text">
|
||||
<string>Shout!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="actionList"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuActions">
|
||||
<property name="title">
|
||||
<string>Actions</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="menuActions"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<property name="windowTitle">
|
||||
<string>toolBar</string>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextUnderIcon</enum>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,97 @@
|
||||
// This is an example not a library
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2008 Daniel Nicoletti <dantti85-pk@yahoo.com.br>
|
||||
SPDX-FileCopyrightText: 2009 Radek Novacek <rnovacek@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "PkExampleHelper.h"
|
||||
#include "examplesadaptor.h"
|
||||
|
||||
#include <polkitqt1-authority.h>
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QTimer>
|
||||
#include <QDebug>
|
||||
#include <QDomDocument>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// This is an example not a library
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2008 Daniel Nicoletti <dantti85-pk@yahoo.com.br>
|
||||
SPDX-FileCopyrightText: 2009 Radek Novacek <rnovacek@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PKEXAMPLE_HELPER_H
|
||||
#define PKEXAMPLE_HELPER_H
|
||||
|
||||
#include <QDBusContext>
|
||||
#include <QCoreApplication>
|
||||
|
||||
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
|
||||
@@ -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
|
||||
)
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include <QDebug>
|
||||
#include <QInputDialog>
|
||||
|
||||
#include "klistener.h"
|
||||
#include <polkitqt1-agent-session.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef POLKIT_QT_AGENT_KDE_LISTENER_H
|
||||
#define POLKIT_QT_AGENT_KDE_LISTENER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
#include <polkitqt1-agent-listener.h>
|
||||
#include <polkitqt1-identity.h>
|
||||
#include <polkitqt1-details.h>
|
||||
#include <polkitqt1-agent-session.h>
|
||||
|
||||
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
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#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();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE 1
|
||||
|
||||
#include <polkitagent/polkitagent.h>
|
||||
#include "pkagentexample.h"
|
||||
#include <glib-object.h>
|
||||
#include <QDebug>
|
||||
#include <polkitqt1-subject.h>
|
||||
|
||||
PkAgentExample::PkAgentExample(int &argc, char **argv)
|
||||
: QCoreApplication(argc, argv)
|
||||
{
|
||||
PolkitQt1::UnixSessionSubject session(getpid());
|
||||
|
||||
m_listener.registerListener(session, "/org/kde/PolicyKit1/AuthenticationAgent");
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// This is an example not a library
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2008 Daniel Nicoletti <dantti85-pk@yahoo.com.br>
|
||||
SPDX-FileCopyrightText: 2009 Radek Novacek <rnovacek@redhat.com>
|
||||
|
||||
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 <QCoreApplication>
|
||||
#include "klistener.h"
|
||||
|
||||
class PkAgentExample : public QCoreApplication
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PkAgentExample(int &argc, char **argv);
|
||||
~PkAgentExample() override {};
|
||||
private:
|
||||
KListener m_listener;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,9 @@
|
||||
<RCC>
|
||||
<qresource prefix="Icons" >
|
||||
<file>action-locked-default.png</file>
|
||||
<file>action-locked.png</file>
|
||||
<file>action-unlocked.png</file>
|
||||
<file>custom-no.png</file>
|
||||
<file>custom-yes.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -0,0 +1,18 @@
|
||||
// This is an example not a library
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2009 Daniel Nicoletti <dantti85-pk@yahoo.com.br>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include "PkExample.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
PkExample example;
|
||||
example.show();
|
||||
return app.exec();
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// This is an example not a library
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2009 Daniel Nicoletti <dantti85-pk@yahoo.com.br>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "PkExampleHelper.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
PkExampleHelper example(argc, argv);
|
||||
return example.exec();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE busconfig PUBLIC
|
||||
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||
<busconfig>
|
||||
|
||||
<!-- This configuration file specifies the required security policies
|
||||
for the PolicyKit examples to work. -->
|
||||
|
||||
<!-- Only user root can own the PackageKit service -->
|
||||
<policy user="root">
|
||||
<allow own="org.qt.policykit.examples"/>
|
||||
</policy>
|
||||
|
||||
<!-- Allow anyone to call into the service - we'll reject callers using PolicyKit -->
|
||||
<policy context="default">
|
||||
<allow send_destination="org.qt.policykit.examples"/>
|
||||
</policy>
|
||||
|
||||
</busconfig>
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
<policyconfig>
|
||||
<vendor>KDE</vendor>
|
||||
<vendor_url>http://www.kde.org</vendor_url>
|
||||
|
||||
<action id="org.qt.policykit.examples.kick">
|
||||
<description>Kick</description>
|
||||
<message>Prevents PolicyKit-Qt example from kicking</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>no</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.qt.policykit.examples.cry">
|
||||
<description>Cry</description>
|
||||
<message>Prevents PolicyKit-Qt example from crying</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.qt.policykit.examples.bleed">
|
||||
<description>Bleed</description>
|
||||
<message>Prevents PolicyKit-Qt example from bleeding</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>auth_self</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.qt.policykit.examples.play">
|
||||
<description>Play</description>
|
||||
<message>Prevents PolicyKit-Qt example from playing</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>auth_admin</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.qt.policykit.examples.listen">
|
||||
<description>Listen</description>
|
||||
<message>Prevents PolicyKit-Qt example from listening</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>auth_self_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.qt.policykit.examples.delete">
|
||||
<description>Delete</description>
|
||||
<message>Prevents PolicyKit-Qt example from deleting</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.qt.policykit.examples.set">
|
||||
<description>Push</description>
|
||||
<message>Prevents PolicyKit-Qt example from setting permissions for the shout action</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.qt.policykit.examples.shout">
|
||||
<description>Shout</description>
|
||||
<message>Prevents PolicyKit-Qt example from shouting</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
<annotate key="org.qt.policykit.examples.shout">foo</annotate>
|
||||
</action>
|
||||
</policyconfig>
|
||||
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
<policyconfig>
|
||||
<vendor>KDE</vendor>
|
||||
<vendor_url>http://www.kde.org</vendor_url>
|
||||
<action id="org.qt.policykit.examples.kick">
|
||||
<description>Kick</description>
|
||||
<message>Prevents PolicyKit-Qt example from kicking</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>no</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
<action id="org.qt.policykit.examples.cry">
|
||||
<description>Cry</description>
|
||||
<message>Prevents PolicyKit-Qt example from crying</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
<action id="org.qt.policykit.examples.play">
|
||||
<description>Play</description>
|
||||
<message>Prevents PolicyKit-Qt example from playing</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>auth_self</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
<action id="org.qt.policykit.examples.bleed">
|
||||
<description>Bleed</description>
|
||||
<message>Prevents PolicyKit-Qt example from bleeding</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>auth_admin</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
<action id="org.qt.policykit.examples.listen">
|
||||
<description>Listen</description>
|
||||
<message>Prevents PolicyKit-Qt example from listening</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>auth_self_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
<action id="org.qt.policykit.examples.delete">
|
||||
<description>Delete</description>
|
||||
<message>Prevents PolicyKit-Qt example from deleting</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
<!--
|
||||
<action id="org.qt.policykit.examples.shout">
|
||||
<description>Shout</description>
|
||||
<message>Prevents PolicyKit-Qt example from shouting</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
<annotate key="org.qt.policykit.examples.shout">foo</annotate>
|
||||
</action>
|
||||
<action id="org.qt.policykit.examples.push">
|
||||
<description>Push</description>
|
||||
<message>Prevents PolicyKit-Qt example from pushing</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
<annotate key="org.qt.policykit.examples.push">bar</annotate>
|
||||
</action>
|
||||
<action id="org.qt.policykit.examples.blow-up">
|
||||
<description>Blow Up</description>
|
||||
<message>Prevents PolicyKit-Qt example from blowing up</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
<annotate key="org.qt.policykit.examples.blow-up">booo</annotate>
|
||||
</action>
|
||||
-->
|
||||
</policyconfig>
|
||||
@@ -0,0 +1,5 @@
|
||||
[D-BUS Service]
|
||||
Name=org.qt.policykit.examples
|
||||
Exec=@BIN_INSTALL_DIR@/@POLKITQT-1_EXAMPLE_HELPER@
|
||||
User=root
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<node>
|
||||
<interface name="org.qt.policykit.examples">
|
||||
<method name="set" >
|
||||
<!-- IN: system user -->
|
||||
<arg direction="in" type="s" name="user" />
|
||||
<!-- OUT: whether the user gained the authorization -->
|
||||
<arg direction="out" type="b" name="shadow_line" />
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
||||
@@ -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_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${POLKITQT-1_INCLUDE_PATH}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
|
||||
)
|
||||
|
||||
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)
|
||||
@@ -0,0 +1,502 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Daniel Nicoletti <dantti85-pk@yahoo.com.br>
|
||||
SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
|
||||
SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "polkitqt1-gui-action.h"
|
||||
#include "polkitqt1-authority.h"
|
||||
#include "polkitqt1-subject.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
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<QAction *>(parent)->setVisible(noVisible);
|
||||
qobject_cast<QAction *>(parent)->setEnabled(noEnabled);
|
||||
qobject_cast<QAction *>(parent)->setText(noText);
|
||||
if (!noWhatsThis.isNull()) {
|
||||
qobject_cast<QAction *>(parent)->setWhatsThis(noWhatsThis);
|
||||
}
|
||||
if (!noToolTip.isNull()) {
|
||||
qobject_cast<QAction *>(parent)->setToolTip(noToolTip);
|
||||
}
|
||||
qobject_cast<QAction *>(parent)->setIcon(noIcon);
|
||||
break;
|
||||
|
||||
case Authority::Challenge:
|
||||
qobject_cast<QAction *>(parent)->setVisible(authVisible);
|
||||
qobject_cast<QAction *>(parent)->setEnabled(authEnabled);
|
||||
qobject_cast<QAction *>(parent)->setText(authText);
|
||||
if (!authWhatsThis.isNull()) {
|
||||
qobject_cast<QAction *>(parent)->setWhatsThis(authWhatsThis);
|
||||
}
|
||||
if (!authToolTip.isNull()) {
|
||||
qobject_cast<QAction *>(parent)->setToolTip(authToolTip);
|
||||
}
|
||||
qobject_cast<QAction *>(parent)->setIcon(authIcon);
|
||||
break;
|
||||
case Authority::Yes:
|
||||
qobject_cast<QAction *>(parent)->setVisible(yesVisible);
|
||||
qobject_cast<QAction *>(parent)->setEnabled(yesEnabled);
|
||||
qobject_cast<QAction *>(parent)->setText(yesText);
|
||||
if (!yesWhatsThis.isNull()) {
|
||||
qobject_cast<QAction *>(parent)->setWhatsThis(yesWhatsThis);
|
||||
}
|
||||
if (!yesToolTip.isNull()) {
|
||||
qobject_cast<QAction *>(parent)->setToolTip(yesToolTip);
|
||||
}
|
||||
qobject_cast<QAction *>(parent)->setIcon(yesIcon);
|
||||
if (parent->isCheckable()) {
|
||||
qobject_cast<QAction *>(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"
|
||||
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Daniel Nicoletti <dantti85-pk@yahoo.com.br>
|
||||
SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef POLKITQT1_GUI_ACTION_H
|
||||
#define POLKITQT1_GUI_ACTION_H
|
||||
|
||||
#include "polkitqt1-gui-export.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
namespace PolkitQt1
|
||||
{
|
||||
|
||||
namespace Gui
|
||||
{
|
||||
|
||||
/**
|
||||
* \class Action polkitqt1-gui-action.h Action
|
||||
* \author Daniel Nicoletti <dantti85-pk@yahoo.com.br>
|
||||
* \author Dario Freddi <drf@kde.org>
|
||||
*
|
||||
* \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
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Daniel Nicoletti <dantti85-pk@yahoo.com.br>
|
||||
SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
|
||||
|
||||
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<QAbstractButton *>() << 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<QAbstractButton *>(q->sender()), c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include "moc_polkitqt1-gui-actionbutton.cpp"
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Daniel Nicoletti <dantti85-pk@yahoo.com.br>
|
||||
SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
|
||||
|
||||
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 <dantti85-pk@yahoo.com.br>
|
||||
* \author Dario Freddi <drf@kde.org>
|
||||
*
|
||||
* \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<ActionButton *>(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
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef POLKITQT1_GUI_ACTIONBUTTON_P_H
|
||||
#define POLKITQT1_GUI_ACTIONBUTTON_P_H
|
||||
|
||||
#include <polkitqt1-gui-actionbutton.h>
|
||||
|
||||
#include <QList>
|
||||
#include <QAbstractButton>
|
||||
|
||||
/**
|
||||
* \internal
|
||||
*/
|
||||
class PolkitQt1::Gui::ActionButtonPrivate
|
||||
{
|
||||
public:
|
||||
ActionButtonPrivate(const QList<QAbstractButton *> &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<QAbstractButton *> buttons;
|
||||
};
|
||||
|
||||
#endif /* ACTIONBUTTON_P_H */
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
|
||||
|
||||
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<QAbstractButton *> &buttons, const QString &actionId, QObject *parent)
|
||||
: ActionButton(*new ActionButtonsPrivate(buttons), actionId, parent)
|
||||
{
|
||||
setButtons(buttons);
|
||||
}
|
||||
|
||||
ActionButtons::~ActionButtons()
|
||||
{
|
||||
}
|
||||
|
||||
void ActionButtons::setButtons(const QList<QAbstractButton *> &buttons)
|
||||
{
|
||||
Q_FOREACH(QAbstractButton *ent, buttons) {
|
||||
addButton(ent);
|
||||
}
|
||||
}
|
||||
|
||||
QList<QAbstractButton *> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
|
||||
|
||||
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 <drf@kde.org>
|
||||
*
|
||||
* \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<QAbstractButton *> &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<QAbstractButton *> &buttons);
|
||||
|
||||
/**
|
||||
* Returns the current buttons list
|
||||
*
|
||||
* \return the buttons currently associated with the underlying action
|
||||
*/
|
||||
QList<QAbstractButton *> 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
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
This file is part of the Polkit-qt project
|
||||
SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
|
||||
|
||||
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<QAbstractButton *> &b)
|
||||
: ActionButtonPrivate(b) {}
|
||||
};
|
||||
|
||||
#endif /* ACTIONBUTTONS_P_H */
|
||||
@@ -0,0 +1 @@
|
||||
#include "../polkitqt1-actiondescription.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../polkitqt1-agent-listener.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../polkitqt1-agent-session.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../polkitqt1-authority.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../polkitqt1-details.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../polkitqt1-gui-action.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../polkitqt1-gui-actionbutton.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../polkitqt1-gui-actionbuttons.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../polkitqt1-identity.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../polkitqt1-subject.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../polkitqt1-temporaryauthorization.h"
|
||||
@@ -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
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -0,0 +1 @@
|
||||
#cmakedefine01 HAVE_POLKIT_SYSTEM_BUS_NAME_GET_USER_SYNC
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2007 Sebastian Trueg <trueg@kde.org>
|
||||
SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
|
||||
|
||||
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
|
||||
@@ -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)
|
||||
@@ -0,0 +1,237 @@
|
||||
|
||||
|
||||
#include "test.h"
|
||||
#include <polkitqt1-authority.h>
|
||||
#include <polkitqt1-agent-session.h>
|
||||
#include <polkitqt1-details.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusConnection>
|
||||
#include <QSignalSpy>
|
||||
|
||||
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<PolkitQt1::Authority::Result>();
|
||||
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<PolkitQt1::ActionDescription::List>();
|
||||
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<QString>();
|
||||
|
||||
|
||||
msg = QDBusMessage::createMethodCall("org.freedesktop.ConsoleKit",
|
||||
"/org/freedesktop/ConsoleKit/Manager",
|
||||
"org.freedesktop.ConsoleKit.Manager",
|
||||
"CloseSession");
|
||||
msg.setArguments(QList<QVariant> () << 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<QString> list = details.keys();
|
||||
QVERIFY(list.contains("1"));
|
||||
QVERIFY(list.contains("2"));
|
||||
QVERIFY(list.contains("3"));
|
||||
QVERIFY(list.contains("4"));
|
||||
}
|
||||
|
||||
QTEST_MAIN(TestAuth)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user