diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 7b91aa1..f2e413d 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -1,65 +1,73 @@ find_package(Qt5Test ${REQUIRED_QT_VERSION} CONFIG QUIET) if(NOT Qt5Test_FOUND) message(STATUS "Qt5Test not found, autotests will not be built.") return() endif() qt5_add_dbus_adaptor(kauth_dbus_adaptor_tests_SRCS ../src/backends/dbus/org.kde.kf5auth.xml ../src/backends/dbus/DBusHelperProxy.h KAuth::DBusHelperProxy) include(ECMAddTests) set(kauthdebug_SRCS) ecm_qt_declare_logging_category(kauthdebug_tests_SRCS HEADER kauthdebug.h IDENTIFIER KAUTH CATEGORY_NAME kf5.kauth) set(libkauth_tests_static_SRCS ../src/kauthaction.cpp ../src/kauthactionreply.cpp ../src/kauthexecutejob.cpp ../src/AuthBackend.cpp # Use our "special" backends manager BackendsManager.cpp ../src/HelperProxy.cpp ../src/kauthhelpersupport.cpp TestBackend.cpp ../src/backends/dbus/DBusHelperProxy.cpp ${kauth_dbus_adaptor_tests_SRCS} ${kauthdebug_tests_SRCS} ) add_library(kauth_tests_static STATIC ${libkauth_tests_static_SRCS}) # make sure all executables using this library have the define set to make sure it builds on MSVC target_compile_definitions(kauth_tests_static PUBLIC KAUTHCORE_STATIC_DEFINE=1 PUBLIC KAUTH_STATIC_DEFINE=1 ) ecm_mark_as_test(kauth_tests_static) target_include_directories(kauth_tests_static PUBLIC $ ${CMAKE_CURRENT_SOURCE_DIR}/../src ) target_link_libraries(kauth_tests_static PUBLIC Qt5::DBus KF5::CoreAddons) ########### next target ############### set(SetupActionTest_SRCS SetupActionTest.cpp) ecm_add_test(${SetupActionTest_SRCS} TEST_NAME KAuthSetupActionTest LINK_LIBRARIES Qt5::Test kauth_tests_static ) ########### next target ############### set(HelperTest_SRCS HelperTest.cpp TestHelper.cpp) ecm_add_test(${HelperTest_SRCS} TEST_NAME KAuthHelperTest LINK_LIBRARIES Qt5::Test kauth_tests_static ) + +########### test kauth-policy-gen ############### +add_test(NAME KAuthPolicyGenTest + COMMAND kauth-policy-gen ${CMAKE_SOURCE_DIR}/autotests/foo_actions.actions + ${CMAKE_BINARY_DIR}/generated-foo.policy) +add_test(KAuthPolicyGenTestCompare ${CMAKE_COMMAND} -E compare_files + ${CMAKE_BINARY_DIR}/generated-foo.policy ${CMAKE_SOURCE_DIR}/autotests/foo.policy) + diff --git a/autotests/foo.policy b/autotests/foo.policy new file mode 100644 index 0000000..9e1a0e4 --- /dev/null +++ b/autotests/foo.policy @@ -0,0 +1,22 @@ + + + +Foo Control Module +preferences-desktop-display + + Desa el tema del Foo + Save the Foo Theme + Save the Foo Theme + 保存 Foo 主题 + Les polítiques del sistema impedeixen que apliqueu el tema del Foo. + System policies prevent you from applying the Foo theme. + System policies prevent you from applying the Foo theme. + 系统策略阻止您应用 Foo 主题。 + + no + auth_admin + + + diff --git a/autotests/foo_actions.actions b/autotests/foo_actions.actions new file mode 100644 index 0000000..303d286 --- /dev/null +++ b/autotests/foo_actions.actions @@ -0,0 +1,23 @@ +[Domain] +Name=Foo Control Module +Name[ca]=Mòdul de control del Foo +Name[ca@valencia]=Mòdul de control del Foo +Name[en_GB]=Foo Control Module +Name[x-test]=xxFoo Control Modulexx +Name[zh_CN]=Foo 控制模块 +Icon=preferences-desktop-display + +[org.kde.kcontrol.kcmplymouth.save] +Name=Save the Foo Theme +Name[ca]=Desa el tema del Foo +Name[ca@valencia]=Guarda el tema de Foo +Name[en_GB]=Save the Foo Theme +Name[x-test]=xxSave the Foo Themexx +Name[zh_CN]=保存 Foo 主题 +Description=System policies prevent you from applying the Foo theme. +Description[ca]=Les polítiques del sistema impedeixen que apliqueu el tema del Foo. +Description[ca@valencia]=Les polítiques del sistema impedeixen que apliqueu el tema de Foo. +Description[en_GB]=System policies prevent you from applying the Foo theme. +Description[x-test]=xxSystem policies prevent you from applying the Foo theme.xx +Description[zh_CN]=系统策略阻止您应用 Foo 主题。 +Policy=auth_admin diff --git a/src/policy-gen/policy-gen.cpp b/src/policy-gen/policy-gen.cpp index bc58919..fec02c0 100644 --- a/src/policy-gen/policy-gen.cpp +++ b/src/policy-gen/policy-gen.cpp @@ -1,177 +1,182 @@ /* * Copyright (C) 2008 Nicola Gigante * Copyright (C) 2009 Dario Freddi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 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 Lesser 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 . */ #include "policy-gen.h" #include #include #include #include #include #include #include #include using namespace std; QList parse(QSettings &ini); QMap parseDomain(QSettings &ini); int main(int argc, char **argv) { QCoreApplication app(argc, argv); if (argc < 2) { qCritical("Too few arguments"); return 1; } QSettings ini(QFile::decodeName(argv[1]), QSettings::IniFormat); ini.setIniCodec("UTF-8"); if (ini.status()) { qCritical("Error loading file: %s", argv[1]); return 1; } if (argc == 3) { // Support an optional 2nd argument pointing to the output file // // This is safer to use in build systems than // "kauth-policy-gen foo.actions > foo.policy" because when using a // redirection "foo.policy" is created even if kauth-policy-gen fails. // This means the first call to make fails, but a second call succeeds // because an empty "foo.policy" exists. if (!freopen(argv[2], "w", stdout)) { qCritical("Failed to open %s for writing: %s", argv[2], strerror(errno)); return 1; } } output(parse(ini), parseDomain(ini)); } QList parse(QSettings &ini) { QList actions; + + // example: [org.kde.kcontrol.kcmfoo.save] const QRegularExpression actionExp(QRegularExpression::anchoredPattern(QStringLiteral("[0-9a-z]+(\\.[0-9a-z]+)*"))); - const QRegularExpression descriptionExp(QRegularExpression::anchoredPattern(QStringLiteral("description(?:\\[(\\w+)\\])?")) - , QRegularExpression::CaseInsensitiveOption); + // example: Description[ca]=Mòdul de control del Foo. + const QRegularExpression descriptionExp(QRegularExpression::anchoredPattern(QStringLiteral("description(?:\\[(\\w+)\\])?")), + QRegularExpression::CaseInsensitiveOption); - const QRegularExpression nameExp(QRegularExpression::anchoredPattern(QStringLiteral("name(?:\\[(\\w+)\\])?")) - , QRegularExpression::CaseInsensitiveOption); + // example: Name[ca]=Mòdul de control del Foo + const QRegularExpression nameExp(QRegularExpression::anchoredPattern(QStringLiteral("name(?:\\[(\\w+)\\])?")), + QRegularExpression::CaseInsensitiveOption); + // example: Policy=auth_admin const QRegularExpression policyExp(QRegularExpression::anchoredPattern(QStringLiteral("(?:yes|no|auth_self|auth_admin)"))); const auto listChilds = ini.childGroups(); for (const QString &name : listChilds) { Action action; if (name == QLatin1String("Domain")) { continue; } if (!actionExp.match(name).hasMatch()) { qCritical("Wrong action syntax: %s\n", name.toLatin1().data()); exit(1); } action.name = name; ini.beginGroup(name); const auto listChildKeys = ini.childKeys(); for (const QString &key : listChildKeys) { QRegularExpressionMatch match; if ((match = descriptionExp.match(key)).hasMatch()) { - QString lang = match.captured(); + QString lang = match.captured(1); if (lang.isEmpty()) { lang = QString::fromLatin1("en"); } action.descriptions.insert(lang, ini.value(key).toString()); } else if ((match = nameExp.match(key)).hasMatch()) { - QString lang = match.captured(); + QString lang = match.captured(1); if (lang.isEmpty()) { lang = QString::fromLatin1("en"); } action.messages.insert(lang, ini.value(key).toString()); } else if (key.toLower() == QLatin1String("policy")) { QString policy = ini.value(key).toString(); if (!policyExp.match(policy).hasMatch()) { qCritical("Wrong policy: %s", policy.toLatin1().data()); exit(1); } action.policy = policy; } else if (key.toLower() == QLatin1String("policyinactive")) { QString policyInactive = ini.value(key).toString(); if (!policyExp.match(policyInactive).hasMatch()) { qCritical("Wrong policy: %s", policyInactive.toLatin1().data()); exit(1); } action.policyInactive = policyInactive; } else if (key.toLower() == QLatin1String("persistence")) { QString persistence = ini.value(key).toString(); if (persistence != QLatin1String("session") && persistence != QLatin1String("always")) { qCritical("Wrong persistence: %s", persistence.toLatin1().data()); exit(1); } action.persistence = persistence; } } if (action.policy.isEmpty() || action.messages.isEmpty() || action.descriptions.isEmpty()) { qCritical("Missing option in action: %s", name.toLatin1().data()); exit(1); } ini.endGroup(); actions.append(action); } return actions; } QMap parseDomain(QSettings &ini) { QMap rethash; if (ini.childGroups().contains(QString::fromLatin1("Domain"))) { if (ini.contains(QString::fromLatin1("Domain/Name"))) { rethash[QString::fromLatin1("vendor")] = ini.value(QString::fromLatin1("Domain/Name")).toString(); } if (ini.contains(QString::fromLatin1("Domain/URL"))) { rethash[QString::fromLatin1("vendorurl")] = ini.value(QString::fromLatin1("Domain/URL")).toString(); } if (ini.contains(QString::fromLatin1("Domain/Icon"))) { rethash[QString::fromLatin1("icon")] = ini.value(QString::fromLatin1("Domain/Icon")).toString(); } } return rethash; }