ldapurl.cpp 6.19 KB
Newer Older
1
/*
Allen Winter's avatar
Allen Winter committed
2
  This file is part of libkldap.
3
4
5
  SPDX-FileCopyrightText: 2004-2006 Szombathelyi György <gyurco@freemail.hu>

  SPDX-License-Identifier: LGPL-2.0-or-later
6
7
*/

Allen Winter's avatar
Allen Winter committed
8
#include "ldapurl.h"
9

Laurent Montel's avatar
Laurent Montel committed
10
#include "ldap_debug.h"
11
12
13
14


using namespace KLDAP;

15
class Q_DECL_HIDDEN LdapUrl::LdapUrlPrivate
16
{
Laurent Montel's avatar
Laurent Montel committed
17
public:
18
    LdapUrlPrivate()
Laurent Montel's avatar
Laurent Montel committed
19
        : m_scope(Base)
20
21
22
23
24
25
26
27
28
    {
    }

    QMap<QString, Extension> m_extensions;
    QStringList m_attributes;
    Scope m_scope;
    QString m_filter;
};

29
LdapUrl::LdapUrl()
Laurent Montel's avatar
Laurent Montel committed
30
    : d(new LdapUrlPrivate)
31
32
33
{
}

Laurent Montel's avatar
Laurent Montel committed
34
LdapUrl::LdapUrl(const QUrl &_url)
Laurent Montel's avatar
Laurent Montel committed
35
36
    : QUrl(_url)
    , d(new LdapUrlPrivate)
37
{
Laurent Montel's avatar
Laurent Montel committed
38
    parseQuery();
39
40
}

Laurent Montel's avatar
Laurent Montel committed
41
LdapUrl::LdapUrl(const LdapUrl &that)
Laurent Montel's avatar
Laurent Montel committed
42
43
    : QUrl(that)
    , d(new LdapUrlPrivate)
44
{
Laurent Montel's avatar
Laurent Montel committed
45
    *d = *that.d;
46
47
}

Laurent Montel's avatar
Laurent Montel committed
48
LdapUrl &LdapUrl::operator=(const LdapUrl &that)
49
{
Laurent Montel's avatar
Laurent Montel committed
50
51
52
    if (this == &that) {
        return *this;
    }
53

Laurent Montel's avatar
Laurent Montel committed
54
55
    QUrl::operator=(that);
    *d = *that.d;
56

Laurent Montel's avatar
Laurent Montel committed
57
    return *this;
58
59
60
61
}

LdapUrl::~LdapUrl()
{
Laurent Montel's avatar
Laurent Montel committed
62
    delete d;
63
64
}

Laurent Montel's avatar
Laurent Montel committed
65
void LdapUrl::setDn(const LdapDN &dn)
66
{
Laurent Montel's avatar
Laurent Montel committed
67
    const QString tmp = dn.toString();
Laurent Montel's avatar
Laurent Montel committed
68
    if (tmp.startsWith(QLatin1Char('/'))) {
69
70
71
        setPath(tmp);
    } else {
        setPath(QLatin1Char('/')  + tmp);
Laurent Montel's avatar
Laurent Montel committed
72
    }
73
74
}

75
LdapDN LdapUrl::dn() const
76
{
Laurent Montel's avatar
Laurent Montel committed
77
78
79
80
81
82
    QString tmp = path();
    if (tmp.startsWith(QLatin1Char('/'))) {
        tmp = tmp.mid(1);
    }
    LdapDN tmpDN(tmp);
    return tmpDN;
83
84
}

85
86
QStringList LdapUrl::attributes() const
{
Laurent Montel's avatar
Laurent Montel committed
87
    return d->m_attributes;
88
89
}

Laurent Montel's avatar
Laurent Montel committed
90
void LdapUrl::setAttributes(const QStringList &attributes)
91
{
Laurent Montel's avatar
Laurent Montel committed
92
93
    d->m_attributes = attributes;
    updateQuery();
94
95
96
97
}

LdapUrl::Scope LdapUrl::scope() const
{
Laurent Montel's avatar
Laurent Montel committed
98
    return d->m_scope;
99
100
}

Laurent Montel's avatar
Laurent Montel committed
101
void LdapUrl::setScope(Scope scope)
102
{
Laurent Montel's avatar
Laurent Montel committed
103
104
    d->m_scope = scope;
    updateQuery();
105
106
107
108
}

QString LdapUrl::filter() const
{
Laurent Montel's avatar
Laurent Montel committed
109
    return d->m_filter;
110
111
}

Laurent Montel's avatar
Laurent Montel committed
112
void LdapUrl::setFilter(const QString &filter)
113
{
Laurent Montel's avatar
Laurent Montel committed
114
115
    d->m_filter = filter;
    updateQuery();
116
117
}

Laurent Montel's avatar
Laurent Montel committed
118
bool LdapUrl::hasExtension(const QString &key) const
119
{
Laurent Montel's avatar
Laurent Montel committed
120
    return d->m_extensions.contains(key);
121
122
}

Laurent Montel's avatar
Laurent Montel committed
123
LdapUrl::Extension LdapUrl::extension(const QString &key) const
124
{
Laurent Montel's avatar
Laurent Montel committed
125
126
127
128
    QMap<QString, Extension>::const_iterator it;

    it = d->m_extensions.constFind(key);
    if (it != d->m_extensions.constEnd()) {
Laurent Montel's avatar
Laurent Montel committed
129
        return *it;
Laurent Montel's avatar
Laurent Montel committed
130
131
132
133
134
135
    } else {
        Extension ext;
        ext.value = QLatin1String("");
        ext.critical = false;
        return ext;
    }
136
137
}

Laurent Montel's avatar
Laurent Montel committed
138
QString LdapUrl::extension(const QString &key, bool &critical) const
139
{
Laurent Montel's avatar
Laurent Montel committed
140
    const Extension ext = extension(key);
Laurent Montel's avatar
Laurent Montel committed
141
142
    critical = ext.critical;
    return ext.value;
143
144
}

Laurent Montel's avatar
Laurent Montel committed
145
void LdapUrl::setExtension(const QString &key, const LdapUrl::Extension &ext)
146
{
Laurent Montel's avatar
Laurent Montel committed
147
148
    d->m_extensions[ key ] = ext;
    updateQuery();
149
150
}

Laurent Montel's avatar
Laurent Montel committed
151
void LdapUrl::setExtension(const QString &key, const QString &value, bool critical)
152
{
Laurent Montel's avatar
Laurent Montel committed
153
154
155
156
    Extension ext;
    ext.value = value;
    ext.critical = critical;
    setExtension(key, ext);
157
158
}

Laurent Montel's avatar
Laurent Montel committed
159
void LdapUrl::setExtension(const QString &key, int value, bool critical)
160
{
Laurent Montel's avatar
Laurent Montel committed
161
162
163
164
    Extension ext;
    ext.value = QString::number(value);
    ext.critical = critical;
    setExtension(key, ext);
165
166
}

Laurent Montel's avatar
Laurent Montel committed
167
void LdapUrl::removeExtension(const QString &key)
168
{
Laurent Montel's avatar
Laurent Montel committed
169
170
    d->m_extensions.remove(key);
    updateQuery();
171
172
173
174
}

void LdapUrl::updateQuery()
{
Laurent Montel's avatar
Laurent Montel committed
175
176
177
178
179
    QMap<QString, Extension>::const_iterator it;
    QString q(QLatin1Char('?'));

    // set the attributes to query
    if (!d->m_attributes.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
180
        q += d->m_attributes.join(QLatin1Char(','));
Laurent Montel's avatar
Laurent Montel committed
181
182
183
184
185
186
    }

    // set the scope
    q += QLatin1Char('?');
    switch (d->m_scope) {
    case Sub:
Laurent Montel's avatar
Laurent Montel committed
187
        q += QStringLiteral("sub");
Laurent Montel's avatar
Laurent Montel committed
188
189
        break;
    case One:
Laurent Montel's avatar
Laurent Montel committed
190
        q += QStringLiteral("one");
Laurent Montel's avatar
Laurent Montel committed
191
192
        break;
    case Base:
Laurent Montel's avatar
Laurent Montel committed
193
        q += QStringLiteral("base");
Laurent Montel's avatar
Laurent Montel committed
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
        break;
    }

    // set the filter
    q += QLatin1Char('?');
    if (d->m_filter != QLatin1String("(objectClass=*)") && !d->m_filter.isEmpty()) {
        q += QLatin1String(toPercentEncoding(d->m_filter));
    }

    // set the extensions
    q += QLatin1Char('?');
    for (it = d->m_extensions.constBegin(); it != d->m_extensions.constEnd(); ++it) {
        if (it.value().critical) {
            q += QLatin1Char('!');
        }
        q += it.key();
        if (!it.value().value.isEmpty()) {
            q += QLatin1Char('=') + QLatin1String(toPercentEncoding(it.value().value));
        }
        q += QLatin1Char(',');
214
    }
Laurent Montel's avatar
Laurent Montel committed
215
216
    while (q.endsWith(QLatin1Char('?')) || q.endsWith(QLatin1Char(','))) {
        q.remove(q.length() - 1, 1);
217
    }
Laurent Montel's avatar
Laurent Montel committed
218
219

    setQuery(q);
Laurent Montel's avatar
Laurent Montel committed
220
    qCDebug(LDAP_LOG) << "LDAP URL updateQuery():" << toDisplayString();
221
222
223
224
}

void LdapUrl::parseQuery()
{
Laurent Montel's avatar
Laurent Montel committed
225
226
    Extension ext;
    QStringList extensions;
227
    QString q = query(QUrl::FullyEncoded);
Laurent Montel's avatar
Laurent Montel committed
228
229
230
    // remove first ?
    if (q.startsWith(QLatin1Char('?'))) {
        q.remove(0, 1);
231
    }
Laurent Montel's avatar
Laurent Montel committed
232
233

    // split into a list
Laurent Montel's avatar
Laurent Montel committed
234
    const QStringList url_items = q.split(QLatin1Char('?'));
Laurent Montel's avatar
Laurent Montel committed
235
236
237

    d->m_attributes.clear();
    d->m_scope = Base;
238
    d->m_filter = QStringLiteral("(objectClass=*)");
Laurent Montel's avatar
Laurent Montel committed
239
240
241
242
243
    d->m_extensions.clear();

    int i = 0;
    QStringList::const_iterator end(url_items.constEnd());
    for (QStringList::const_iterator it = url_items.constBegin();
Laurent Montel's avatar
Laurent Montel committed
244
         it != end; ++it, i++) {
Laurent Montel's avatar
Laurent Montel committed
245
246
        switch (i) {
        case 0:
247
            d->m_attributes = (*it).split(QLatin1Char(','), Qt::SkipEmptyParts);
Laurent Montel's avatar
Laurent Montel committed
248
249
250
251
252
253
254
255
256
257
258
259
            break;
        case 1:
            if ((*it) == QLatin1String("sub")) {
                d->m_scope = Sub;
            } else if ((*it) == QLatin1String("one")) {
                d->m_scope = One;
            }
            break;
        case 2:
            d->m_filter = fromPercentEncoding((*it).toLatin1());
            break;
        case 3:
260
            extensions = (*it).split(QLatin1Char(','), Qt::SkipEmptyParts);
Laurent Montel's avatar
Laurent Montel committed
261
262
263
264
265
266
267
            break;
        }
    }

    QString name, value;
    QStringList::const_iterator end2(extensions.constEnd());
    for (QStringList::const_iterator it = extensions.constBegin();
Laurent Montel's avatar
Laurent Montel committed
268
         it != end2; ++it) {
Laurent Montel's avatar
Laurent Montel committed
269
270
271
272
273
274
275
        ext.critical = false;
        name = fromPercentEncoding((*it).section(QLatin1Char('='), 0, 0).toLatin1()).toLower();
        value = fromPercentEncoding((*it).section(QLatin1Char('='), 1).toLatin1());
        if (name.startsWith(QLatin1Char('!'))) {
            ext.critical = true;
            name.remove(0, 1);
        }
Laurent Montel's avatar
Laurent Montel committed
276
        qCDebug(LDAP_LOG) << "LdapUrl extensions name=" << name << "value:" << value;
Laurent Montel's avatar
Laurent Montel committed
277
278
        ext.value = value.replace(QLatin1String("%2"), QLatin1String(","));
        setExtension(name, ext);
279
280
    }
}