keepassxc

Форк
0
/
DBusTypes.cpp 
216 строк · 8.8 Кб
1
/*
2
 *  Copyright (C) 2019 Aetf <aetf@unlimitedcodeworks.xyz>
3
 *  Copyright 2010, Michael Leupold <lemma@confuego.org>
4
 *
5
 *  This program is free software: you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation, either version 2 or (at your option)
8
 *  version 3 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18

19
#include "fdosecrets/objects/Collection.h"
20
#include "fdosecrets/objects/Item.h"
21
#include "fdosecrets/objects/Prompt.h"
22
#include "fdosecrets/objects/Service.h"
23
#include "fdosecrets/objects/Session.h"
24

25
#include <QDBusMetaType>
26

27
namespace FdoSecrets
28
{
29
    bool inherits(const QMetaObject* derived, const QMetaObject* base)
30
    {
31
        for (auto super = derived; super; super = super->superClass()) {
32
            if (super == base) {
33
                return true;
34
            }
35
        }
36
        return false;
37
    }
38

39
    template <typename T> void registerConverter(const QWeakPointer<DBusMgr>& weak)
40
    {
41
        // from parameter type to on-the-wire type
42
        QMetaType::registerConverter<T*, QDBusObjectPath>([](const T* obj) { return DBusMgr::objectPathSafe(obj); });
43
        QMetaType::registerConverter<QList<T*>, QList<QDBusObjectPath>>(
44
            [](const QList<T*> objs) { return DBusMgr::objectsToPath(objs); });
45

46
        // the opposite
47
        QMetaType::registerConverter<QDBusObjectPath, T*>([weak](const QDBusObjectPath& path) -> T* {
48
            if (auto dbus = weak.lock()) {
49
                return dbus->pathToObject<T>(path);
50
            }
51
            qDebug() << "No DBusMgr when looking up path" << path.path();
52
            return nullptr;
53
        });
54
        QMetaType::registerConverter<QList<QDBusObjectPath>, QList<T*>>([weak](const QList<QDBusObjectPath>& paths) {
55
            if (auto dbus = weak.lock()) {
56
                return dbus->pathsToObject<T>(paths);
57
            }
58
            qDebug() << "No DBusMgr when looking up paths";
59
            return QList<T*>{};
60
        });
61
    }
62

63
    void registerDBusTypes(const QSharedPointer<DBusMgr>& dbus)
64
    {
65
        // On the wire types:
66
        // - various primary types
67
        // - QDBusVariant
68
        // - wire::Secret
69
        // - wire::ObjectPathSecretMap
70
        // - QDBusObjectPath
71
        // - QList<QDBusObjectPath>
72

73
        // Parameter types:
74
        // - various primary types
75
        // - QVariant
76
        // - Secret
77
        // - ObjectSecretMap
78
        // - DBusObject* (and derived classes)
79
        // - QList<DBusObject*>
80

81
        // NOTE: when registering, in additional to the class' fully qualified name,
82
        // the partial-namespace/non-namespace name should also be registered as alias
83
        // otherwise all those usages in Q_INVOKABLE methods without FQN won't be included
84
        // in the meta type system.
85
#define REG_METATYPE(type)                                                                                             \
86
    qRegisterMetaType<type>();                                                                                         \
87
    qRegisterMetaType<type>(#type)
88

89
        // register on-the-wire types
90
        // Qt container types for builtin types don't need registration
91
        REG_METATYPE(wire::Secret);
92
        REG_METATYPE(wire::StringStringMap);
93
        REG_METATYPE(wire::ObjectPathSecretMap);
94

95
        qDBusRegisterMetaType<wire::Secret>();
96
        qDBusRegisterMetaType<wire::StringStringMap>();
97
        qDBusRegisterMetaType<wire::ObjectPathSecretMap>();
98

99
        // register parameter types
100
        REG_METATYPE(Secret);
101
        REG_METATYPE(StringStringMap);
102
        REG_METATYPE(ItemSecretMap);
103
        REG_METATYPE(DBusResult);
104
        REG_METATYPE(DBusClientPtr);
105

106
#define REG_DBUS_OBJ(name)                                                                                             \
107
    REG_METATYPE(name*);                                                                                               \
108
    REG_METATYPE(QList<name*>)
109
        REG_DBUS_OBJ(DBusObject);
110
        REG_DBUS_OBJ(Service);
111
        REG_DBUS_OBJ(Collection);
112
        REG_DBUS_OBJ(Item);
113
        REG_DBUS_OBJ(Session);
114
        REG_DBUS_OBJ(PromptBase);
115
#undef REG_DBUS_OBJ
116

117
#undef REG_METATYPE
118

119
        QWeakPointer<DBusMgr> weak = dbus;
120
        // register converter between on-the-wire types and parameter types
121
        // some pairs are missing because that particular direction isn't used
122
        registerConverter<DBusObject>(weak);
123
        registerConverter<Service>(weak);
124
        registerConverter<Collection>(weak);
125
        registerConverter<Item>(weak);
126
        registerConverter<Session>(weak);
127
        registerConverter<PromptBase>(weak);
128

129
        QMetaType::registerConverter<wire::Secret, Secret>(
130
            [weak](const wire::Secret& from) { return from.unmarshal(weak); });
131
        QMetaType::registerConverter(&Secret::marshal);
132

133
        QMetaType::registerConverter<ItemSecretMap, wire::ObjectPathSecretMap>([](const ItemSecretMap& map) {
134
            wire::ObjectPathSecretMap ret;
135
            for (auto it = map.constBegin(); it != map.constEnd(); ++it) {
136
                ret.insert(it.key()->objectPath(), it.value().marshal());
137
            }
138
            return ret;
139
        });
140

141
        QMetaType::registerConverter<QDBusVariant, QVariant>([](const QDBusVariant& obj) { return obj.variant(); });
142
        QMetaType::registerConverter<QVariant, QDBusVariant>([](const QVariant& obj) { return QDBusVariant(obj); });
143

144
        // structural types are received as QDBusArgument,
145
        // top level QDBusArgument in method parameters are directly handled
146
        // in prepareInputParams.
147
        // But in Collection::createItem, we need to convert a inner QDBusArgument to StringStringMap
148
        QMetaType::registerConverter<QDBusArgument, StringStringMap>([](const QDBusArgument& arg) {
149
            if (arg.currentSignature() != "a{ss}") {
150
                return StringStringMap{};
151
            }
152
            // QDBusArgument is COW and qdbus_cast modifies it by detaching even it is const.
153
            // we don't want to modify the instance (arg) stored in the qvariant so we create a copy
154
            const auto copy = arg; // NOLINT(performance-unnecessary-copy-initialization)
155
            return qdbus_cast<StringStringMap>(copy);
156
        });
157
    }
158

159
    ParamData typeToWireType(int id)
160
    {
161
        switch (id) {
162
        case QMetaType::QString:
163
            return {QByteArrayLiteral("s"), QMetaType::QString};
164
        case QMetaType::QVariant:
165
            return {QByteArrayLiteral("v"), qMetaTypeId<QDBusVariant>()};
166
        case QMetaType::QVariantMap:
167
            return {QByteArrayLiteral("a{sv}"), QMetaType::QVariantMap};
168
        case QMetaType::Bool:
169
            return {QByteArrayLiteral("b"), QMetaType::Bool};
170
        case QMetaType::ULongLong:
171
            return {QByteArrayLiteral("t"), QMetaType::ULongLong};
172
        default:
173
            break;
174
        }
175
        if (id == qMetaTypeId<StringStringMap>()) {
176
            return {QByteArrayLiteral("a{ss}"), qMetaTypeId<wire::StringStringMap>()};
177
        } else if (id == qMetaTypeId<ItemSecretMap>()) {
178
            return {QByteArrayLiteral("a{o(oayays)}"), qMetaTypeId<wire::ObjectPathSecretMap>()};
179
        } else if (id == qMetaTypeId<Secret>()) {
180
            return {QByteArrayLiteral("(oayays)"), qMetaTypeId<wire::Secret>()};
181
        } else if (id == qMetaTypeId<DBusObject*>()) {
182
            return {QByteArrayLiteral("o"), qMetaTypeId<QDBusObjectPath>()};
183
        } else if (id == qMetaTypeId<QList<DBusObject*>>()) {
184
            return {QByteArrayLiteral("ao"), qMetaTypeId<QList<QDBusObjectPath>>()};
185
        }
186

187
        QMetaType mt(id);
188
        if (!mt.isValid()) {
189
            return {};
190
        }
191
        if (QByteArray(QMetaType::typeName(id)).startsWith("QList")) {
192
            // QList<Object*>
193
            return {QByteArrayLiteral("ao"), qMetaTypeId<QList<QDBusObjectPath>>()};
194
        }
195
        if (!inherits(mt.metaObject(), &DBusObject::staticMetaObject)) {
196
            return {};
197
        }
198
        // DBusObjects
199
        return {QByteArrayLiteral("o"), qMetaTypeId<QDBusObjectPath>()};
200
    }
201

202
    ::FdoSecrets::Secret wire::Secret::unmarshal(const QWeakPointer<DBusMgr>& weak) const
203
    {
204
        if (auto dbus = weak.lock()) {
205
            return {dbus->pathToObject<Session>(session), parameters, value, contentType};
206
        }
207
        qDebug() << "No DBusMgr when converting wire::Secret";
208
        return {nullptr, parameters, value, contentType};
209
    }
210

211
    wire::Secret Secret::marshal() const
212
    {
213
        return {DBusMgr::objectPathSafe(session), parameters, value, contentType};
214
    }
215

216
} // namespace FdoSecrets
217

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.