KAuth

policy-gen.cpp
1/*
2 SPDX-FileCopyrightText: 2008 Nicola Gigante <nicola.gigante@gmail.com>
3 SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.1-or-later
6*/
7
8#include "policy-gen.h"
9
10#include <QCoreApplication>
11#include <QDebug>
12#include <QFile>
13#include <QRegularExpression>
14#include <QSettings>
15#include <QStringList>
16
17#include <cerrno>
18#include <cstdio>
19
20using namespace std;
21
23QMap<QString, QString> parseDomain(const QSettings &ini);
24
25int main(int argc, char **argv)
26{
27 QCoreApplication app(argc, argv);
28
29 if (argc < 2) {
30 qCritical("Too few arguments");
31 return 1;
32 }
33
35 if (ini.status()) {
36 qCritical("Error loading file: %s", argv[1]);
37 return 1;
38 }
39
40 if (argc == 3) {
41 // Support an optional 2nd argument pointing to the output file
42 //
43 // This is safer to use in build systems than
44 // "kauth-policy-gen foo.actions > foo.policy" because when using a
45 // redirection "foo.policy" is created even if kauth-policy-gen fails.
46 // This means the first call to make fails, but a second call succeeds
47 // because an empty "foo.policy" exists.
48 if (!freopen(argv[2], "w", stdout)) {
49 qCritical("Failed to open %s for writing: %s", argv[2], strerror(errno));
50 return 1;
51 }
52 }
53
54 output(parse(ini), parseDomain(ini));
55}
56
58{
59 // clazy:excludeall=use-static-qregularexpression
60 // example: [org.kde.kcontrol.kcmfoo.save]
61 const QRegularExpression actionExp(QRegularExpression::anchoredPattern(QStringLiteral("[0-9a-z]+(\\.[0-9a-z]+)*")));
62 // example: Description[ca]=Mòdul de control del Foo.
63 const QRegularExpression descriptionExp(QRegularExpression::anchoredPattern(QStringLiteral("description(?:\\[(\\w+)\\])?")),
65 // example: Name[ca]=Mòdul de control del Foo
66 const QRegularExpression nameExp(QRegularExpression::anchoredPattern(QStringLiteral("name(?:\\[(\\w+)\\])?")), QRegularExpression::CaseInsensitiveOption);
67 // example: Policy=auth_admin
68 const QRegularExpression policyExp(QRegularExpression::anchoredPattern(QStringLiteral("(?:yes|no|auth_self|auth_admin)")));
69
70 QList<Action> actions;
71 const auto listChilds = ini.childGroups();
72 for (const QString &name : listChilds) {
73 Action action;
74
75 if (name == QLatin1String("Domain")) {
76 continue;
77 }
78
79 if (!actionExp.match(name).hasMatch()) {
80 qCritical("Wrong action syntax: %s\n", name.toLatin1().data());
81 exit(1);
82 }
83
84 action.name = name;
85 ini.beginGroup(name);
86
87 const QStringList listChildKeys = ini.childKeys();
88 for (const QString &key : listChildKeys) {
90 if ((match = descriptionExp.match(key)).hasMatch()) {
91 QString lang = match.captured(1);
92
93 if (lang.isEmpty()) {
94 lang = QString::fromLatin1("en");
95 }
96
97 action.descriptions.insert(lang, ini.value(key).toString());
98
99 } else if ((match = nameExp.match(key)).hasMatch()) {
100 QString lang = match.captured(1);
101
102 if (lang.isEmpty()) {
103 lang = QString::fromLatin1("en");
104 }
105
106 action.messages.insert(lang, ini.value(key).toString());
107
108 } else if (key.toLower() == QLatin1String("policy")) {
109 QString policy = ini.value(key).toString();
110 if (!policyExp.match(policy).hasMatch()) {
111 qCritical("Wrong policy: %s", policy.toLatin1().data());
112 exit(1);
113 }
114 action.policy = policy;
115
116 } else if (key.toLower() == QLatin1String("policyinactive")) {
117 QString policyInactive = ini.value(key).toString();
118 if (!policyExp.match(policyInactive).hasMatch()) {
119 qCritical("Wrong policy: %s", policyInactive.toLatin1().data());
120 exit(1);
121 }
122 action.policyInactive = policyInactive;
123
124 } else if (key.toLower() == QLatin1String("persistence")) {
125 QString persistence = ini.value(key).toString();
126 if (persistence != QLatin1String("session") && persistence != QLatin1String("always")) {
127 qCritical("Wrong persistence: %s", persistence.toLatin1().data());
128 exit(1);
129 }
130 action.persistence = persistence;
131 }
132 }
133
134 if (action.policy.isEmpty() || action.messages.isEmpty() || action.descriptions.isEmpty()) {
135 qCritical("Missing option in action: %s", name.toLatin1().data());
136 exit(1);
137 }
138 ini.endGroup();
139
140 actions.append(action);
141 }
142
143 return actions;
144}
145
146QMap<QString, QString> parseDomain(const QSettings &ini)
147{
149
150 if (ini.childGroups().contains(QString::fromLatin1("Domain"))) {
151 if (ini.contains(QString::fromLatin1("Domain/Name"))) {
152 rethash[QString::fromLatin1("vendor")] = ini.value(QString::fromLatin1("Domain/Name")).toString();
153 }
154 if (ini.contains(QString::fromLatin1("Domain/URL"))) {
155 rethash[QString::fromLatin1("vendorurl")] = ini.value(QString::fromLatin1("Domain/URL")).toString();
156 }
157 if (ini.contains(QString::fromLatin1("Domain/Icon"))) {
158 rethash[QString::fromLatin1("icon")] = ini.value(QString::fromLatin1("Domain/Icon")).toString();
159 }
160 }
161
162 return rethash;
163}
KCOREADDONS_EXPORT Result match(QStringView pattern, QStringView str)
QList< QVariant > parse(const QString &message, const QDateTime &externalIssueDateTime=QDateTime())
QString name(StandardAction id)
char * data()
QString decodeName(const QByteArray &localFileName)
void append(QList< T > &&value)
iterator insert(const Key &key, const T &value)
bool isEmpty() const const
QString anchoredPattern(QStringView expression)
void beginGroup(QAnyStringView prefix)
QStringList childGroups() const const
QStringList childKeys() const const
bool contains(QAnyStringView key) const const
void endGroup()
QVariant value(QAnyStringView key) const const
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
QByteArray toLatin1() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 11 2024 12:15:00 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.