1 /*
2  * Copyright (C) 2008-2021 The QXmpp developers
3  *
4  * Author:
5  *  Jeremy Lainé
6  *  Linus Jahn
7  *
8  * Source:
9  *  https://github.com/qxmpp-project/qxmpp
10  *
11  * This file is a part of QXmpp library.
12  *
13  * This library is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU Lesser General Public
15  * License as published by the Free Software Foundation; either
16  * version 2.1 of the License, or (at your option) any later version.
17  *
18  * This library is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21  * Lesser General Public License for more details.
22  *
23  */
24 
25 #include "QXmppRegisterIq.h"
26 
27 #include "QXmppBitsOfBinaryDataList.h"
28 #include "QXmppConstants_p.h"
29 
30 #include <QDomElement>
31 #include <QSharedData>
32 
33 #define ELEMENT_REGISTERED QStringLiteral("registered")
34 #define ELEMENT_REMOVE QStringLiteral("remove")
35 
36 class QXmppRegisterIqPrivate : public QSharedData
37 {
38 public:
39     QXmppRegisterIqPrivate();
40 
41     QXmppDataForm form;
42     QString email;
43     QString instructions;
44     QString password;
45     QString username;
46     bool isRegistered;
47     bool isRemove;
48     QXmppBitsOfBinaryDataList bitsOfBinaryData;
49 };
50 
QXmppRegisterIqPrivate()51 QXmppRegisterIqPrivate::QXmppRegisterIqPrivate()
52     : isRegistered(false),
53       isRemove(false)
54 {
55 }
56 
QXmppRegisterIq()57 QXmppRegisterIq::QXmppRegisterIq()
58     : d(new QXmppRegisterIqPrivate)
59 {
60 }
61 
62 QXmppRegisterIq::QXmppRegisterIq(const QXmppRegisterIq &other) = default;
63 
64 QXmppRegisterIq::~QXmppRegisterIq() = default;
65 
66 QXmppRegisterIq &QXmppRegisterIq::operator=(const QXmppRegisterIq &other) = default;
67 
68 /// Constructs a regular change password request.
69 ///
70 /// \param username The username of the account of which the password should be
71 /// changed.
72 /// \param newPassword The new password that should be set.
73 /// \param to Optional JID of the registration service. If this is omitted, the
74 /// IQ is automatically addressed to the local server.
75 ///
76 /// \since QXmpp 1.2
77 
createChangePasswordRequest(const QString & username,const QString & newPassword,const QString & to)78 QXmppRegisterIq QXmppRegisterIq::createChangePasswordRequest(const QString &username, const QString &newPassword, const QString &to)
79 {
80     QXmppRegisterIq iq;
81     iq.setType(QXmppIq::Set);
82     iq.setTo(to);
83     iq.setUsername(username);
84     iq.setPassword(newPassword);
85     return iq;
86 }
87 
88 /// Constructs a regular unregistration request.
89 ///
90 /// \param to Optional JID of the registration service. If this is omitted, the
91 /// IQ is automatically addressed to the local server.
92 ///
93 /// \since QXmpp 1.2
94 
createUnregistrationRequest(const QString & to)95 QXmppRegisterIq QXmppRegisterIq::createUnregistrationRequest(const QString &to)
96 {
97     QXmppRegisterIq iq;
98     iq.setType(QXmppIq::Set);
99     iq.setTo(to);
100     iq.setIsRemove(true);
101     return iq;
102 }
103 
104 /// Returns the email for this registration IQ.
105 
email() const106 QString QXmppRegisterIq::email() const
107 {
108     return d->email;
109 }
110 
111 /// Sets the \a email for this registration IQ.
112 
setEmail(const QString & email)113 void QXmppRegisterIq::setEmail(const QString &email)
114 {
115     d->email = email;
116 }
117 
118 /// Returns the QXmppDataForm for this registration IQ.
119 
form() const120 QXmppDataForm QXmppRegisterIq::form() const
121 {
122     return d->form;
123 }
124 
125 /// Sets the QXmppDataForm for this registration IQ.
126 ///
127 /// \param form
128 
setForm(const QXmppDataForm & form)129 void QXmppRegisterIq::setForm(const QXmppDataForm &form)
130 {
131     d->form = form;
132 }
133 
134 /// Returns the instructions for this registration IQ.
135 
instructions() const136 QString QXmppRegisterIq::instructions() const
137 {
138     return d->instructions;
139 }
140 
141 /// Sets the \a instructions for this registration IQ.
142 
setInstructions(const QString & instructions)143 void QXmppRegisterIq::setInstructions(const QString &instructions)
144 {
145     d->instructions = instructions;
146 }
147 
148 /// Returns the password for this registration IQ.
149 
password() const150 QString QXmppRegisterIq::password() const
151 {
152     return d->password;
153 }
154 
155 /// Sets the \a password for this registration IQ.
156 
setPassword(const QString & password)157 void QXmppRegisterIq::setPassword(const QString &password)
158 {
159     d->password = password;
160 }
161 
162 /// Returns the username for this registration IQ.
163 
username() const164 QString QXmppRegisterIq::username() const
165 {
166     return d->username;
167 }
168 
169 /// Sets the \a username for this registration IQ.
170 
setUsername(const QString & username)171 void QXmppRegisterIq::setUsername(const QString &username)
172 {
173     d->username = username;
174 }
175 
176 ///
177 /// Returns whether the account is registered.
178 ///
179 /// By default this is set to false.
180 ///
181 /// \since QXmpp 1.2
182 ///
isRegistered() const183 bool QXmppRegisterIq::isRegistered() const
184 {
185     return d->isRegistered;
186 }
187 
188 ///
189 /// Sets whether the account is registered.
190 ///
191 /// By default this is set to false.
192 ///
193 /// \since QXmpp 1.2
194 ///
setIsRegistered(bool isRegistered)195 void QXmppRegisterIq::setIsRegistered(bool isRegistered)
196 {
197     d->isRegistered = isRegistered;
198 }
199 
200 ///
201 /// Returns whether to remove (unregister) the account.
202 ///
203 /// By default this is set to false.
204 ///
205 /// \since QXmpp 1.2
206 ///
isRemove() const207 bool QXmppRegisterIq::isRemove() const
208 {
209     return d->isRemove;
210 }
211 
212 ///
213 /// Sets whether to remove (unregister) the account.
214 ///
215 /// By default this is set to false.
216 ///
217 /// \since QXmpp 1.2
218 ///
setIsRemove(bool isRemove)219 void QXmppRegisterIq::setIsRemove(bool isRemove)
220 {
221     d->isRemove = isRemove;
222 }
223 
224 ///
225 /// Returns a list of data packages attached using \xep{0231}: Bits of Binary.
226 ///
227 /// This could be used to resolve a \c cid: URL of an CAPTCHA field of the
228 /// form.
229 ///
230 /// \since QXmpp 1.2
231 ///
bitsOfBinaryData() const232 QXmppBitsOfBinaryDataList QXmppRegisterIq::bitsOfBinaryData() const
233 {
234     return d->bitsOfBinaryData;
235 }
236 
237 ///
238 /// Returns a list of data attached using \xep{0231}: Bits of Binary.
239 ///
240 /// This could be used to resolve a \c cid: URL of an CAPTCHA field of the
241 /// form.
242 ///
243 /// \since QXmpp 1.2
244 ///
bitsOfBinaryData()245 QXmppBitsOfBinaryDataList &QXmppRegisterIq::bitsOfBinaryData()
246 {
247     return d->bitsOfBinaryData;
248 }
249 
250 ///
251 /// Sets a list of \xep{0231}: Bits of Binary attachments to be included.
252 ///
253 /// \since QXmpp 1.2
254 ///
setBitsOfBinaryData(const QXmppBitsOfBinaryDataList & bitsOfBinaryData)255 void QXmppRegisterIq::setBitsOfBinaryData(const QXmppBitsOfBinaryDataList &bitsOfBinaryData)
256 {
257     d->bitsOfBinaryData = bitsOfBinaryData;
258 }
259 
260 /// \cond
isRegisterIq(const QDomElement & element)261 bool QXmppRegisterIq::isRegisterIq(const QDomElement &element)
262 {
263     return (element.firstChildElement(QStringLiteral("query")).namespaceURI() == ns_register);
264 }
265 
parseElementFromChild(const QDomElement & element)266 void QXmppRegisterIq::parseElementFromChild(const QDomElement &element)
267 {
268     QDomElement queryElement = element.firstChildElement(QStringLiteral("query"));
269     d->instructions = queryElement.firstChildElement(QStringLiteral("instructions")).text();
270     d->username = queryElement.firstChildElement(QStringLiteral("username")).text();
271     d->password = queryElement.firstChildElement(QStringLiteral("password")).text();
272     d->email = queryElement.firstChildElement(QStringLiteral("email")).text();
273     d->form.parse(queryElement.firstChildElement(QStringLiteral("x")));
274     d->isRegistered = !queryElement.firstChildElement(ELEMENT_REGISTERED).isNull();
275     d->isRemove = !queryElement.firstChildElement(ELEMENT_REMOVE).isNull();
276     d->bitsOfBinaryData.parse(queryElement);
277 }
278 
toXmlElementFromChild(QXmlStreamWriter * writer) const279 void QXmppRegisterIq::toXmlElementFromChild(QXmlStreamWriter *writer) const
280 {
281     writer->writeStartElement(QStringLiteral("query"));
282     writer->writeDefaultNamespace(ns_register);
283 
284     if (!d->instructions.isEmpty())
285         writer->writeTextElement(QStringLiteral("instructions"), d->instructions);
286 
287     if (d->isRegistered)
288         writer->writeEmptyElement(ELEMENT_REGISTERED);
289     if (d->isRemove)
290         writer->writeEmptyElement(ELEMENT_REMOVE);
291 
292     if (!d->username.isEmpty())
293         writer->writeTextElement(QStringLiteral("username"), d->username);
294     else if (!d->username.isNull())
295         writer->writeEmptyElement(QStringLiteral("username"));
296 
297     if (!d->password.isEmpty())
298         writer->writeTextElement(QStringLiteral("password"), d->password);
299     else if (!d->password.isNull())
300         writer->writeEmptyElement(QStringLiteral("password"));
301 
302     if (!d->email.isEmpty())
303         writer->writeTextElement(QStringLiteral("email"), d->email);
304     else if (!d->email.isNull())
305         writer->writeEmptyElement(QStringLiteral("email"));
306 
307     d->form.toXml(writer);
308     d->bitsOfBinaryData.toXml(writer);
309 
310     writer->writeEndElement();
311 }
312 
313 /// \endcond
314