gloox 1.0.28
registration.cpp
1/*
2 Copyright (c) 2005-2023 by Jakob Schröter <js@camaya.net>
3 This file is part of the gloox library. http://camaya.net/gloox
4
5 This software is distributed under a license. The full license
6 agreement can be found in the file LICENSE in this distribution.
7 This software may not be copied, modified, sold or distributed
8 other than expressed in the named license agreement.
9
10 This software is distributed without any warranty.
11*/
12
13
14#include "registration.h"
15
16#include "clientbase.h"
17#include "stanza.h"
18#include "error.h"
19#include "prep.h"
20#include "oob.h"
21
22namespace gloox
23{
24
25 // Registration::Query ----
27 : StanzaExtension( ExtRegistration ), m_form( form ), m_fields( 0 ), m_oob( 0 ),
28 m_del( false ), m_reg( false )
29 {
30 }
31
33 : StanzaExtension( ExtRegistration ), m_form( 0 ), m_fields( 0 ), m_oob( 0 ), m_del( del ),
34 m_reg( false )
35 {
36 }
37
39 : StanzaExtension( ExtRegistration ), m_form( 0 ), m_fields( fields ), m_values( values ),
40 m_oob( 0 ), m_del( false ), m_reg( false )
41 {
42 }
43
45 : StanzaExtension( ExtRegistration ), m_form( 0 ), m_fields( 0 ), m_oob( 0 ), m_del( false ),
46 m_reg( false )
47 {
48 if( !tag || tag->name() != "query" || tag->xmlns() != XMLNS_REGISTER )
49 return;
50
51 const TagList& l = tag->children();
52 TagList::const_iterator it = l.begin();
53 for( ; it != l.end(); ++it )
54 {
55 const std::string& name = (*it)->name();
56 if( name == "instructions" )
57 m_instructions = (*it)->cdata();
58 else if( name == "remove" )
59 m_del = true;
60 else if( name == "registered" )
61 m_reg = true;
62 else if( name == "username" )
63 {
64 m_fields |= FieldUsername;
65 m_values.username = (*it)->cdata();
66 }
67 else if( name == "nick" )
68 {
69 m_fields |= FieldNick;
70 m_values.nick = (*it)->cdata();
71 }
72 else if( name == "password" )
73 {
74 m_fields |= FieldPassword;
75 m_values.password = (*it)->cdata();
76 }
77 else if( name == "name" )
78 {
79 m_fields |= FieldName;
80 m_values.name = (*it)->cdata();
81 }
82 else if( name == "first" )
83 {
84 m_fields |= FieldFirst;
85 m_values.first = (*it)->cdata();
86 }
87 else if( name == "last" )
88 {
89 m_fields |= FieldLast;
90 m_values.last = (*it)->cdata();
91 }
92 else if( name == "email" )
93 {
94 m_fields |= FieldEmail;
95 m_values.email = (*it)->cdata();
96 }
97 else if( name == "address" )
98 {
99 m_fields |= FieldAddress;
100 m_values.address = (*it)->cdata();
101 }
102 else if( name == "city" )
103 {
104 m_fields |= FieldCity;
105 m_values.city = (*it)->cdata();
106 }
107 else if( name == "state" )
108 {
109 m_fields |= FieldState;
110 m_values.state = (*it)->cdata();
111 }
112 else if( name == "zip" )
113 {
114 m_fields |= FieldZip;
115 m_values.zip = (*it)->cdata();
116 }
117 else if( name == "phone" )
118 {
119 m_fields |= FieldPhone;
120 m_values.phone = (*it)->cdata();
121 }
122 else if( name == "url" )
123 {
124 m_fields |= FieldUrl;
125 m_values.url = (*it)->cdata();
126 }
127 else if( name == "date" )
128 {
129 m_fields |= FieldDate;
130 m_values.date = (*it)->cdata();
131 }
132 else if( name == "misc" )
133 {
134 m_fields |= FieldMisc;
135 m_values.misc = (*it)->cdata();
136 }
137 else if( name == "text" )
138 {
139 m_fields |= FieldText;
140 m_values.text = (*it)->cdata();
141 }
142 else if( !m_form && name == "x" && (*it)->xmlns() == XMLNS_X_DATA )
143 m_form = new DataForm( (*it) );
144 else if( !m_oob && name == "x" && (*it)->xmlns() == XMLNS_X_OOB )
145 m_oob = new OOB( (*it) );
146 }
147 }
148
150 {
151 delete m_form;
152 delete m_oob;
153 }
154
155 const std::string& Registration::Query::filterString() const
156 {
157 static const std::string filter = "/iq/query[@xmlns='" + XMLNS_REGISTER + "']";
158 return filter;
159 }
160
162 {
163 Tag* t = new Tag( "query" );
165
166 if( !m_instructions.empty() )
167 new Tag( t, "instructions", m_instructions );
168
169 if ( m_reg )
170 new Tag( t, "registered" );
171
172 if( m_form )
173 t->addChild( m_form->tag() );
174 else if( m_oob )
175 t->addChild( m_oob->tag() );
176 else if( m_del )
177 new Tag( t, "remove" );
178 else if( m_fields )
179 {
180 if( m_fields & FieldUsername )
181 new Tag( t, "username", m_values.username );
182 if( m_fields & FieldNick )
183 new Tag( t, "nick", m_values.nick );
184 if( m_fields & FieldPassword )
185 new Tag( t, "password", m_values.password );
186 if( m_fields & FieldName )
187 new Tag( t, "name", m_values.name );
188 if( m_fields & FieldFirst )
189 new Tag( t, "first", m_values.first );
190 if( m_fields & FieldLast )
191 new Tag( t, "last", m_values.last );
192 if( m_fields & FieldEmail )
193 new Tag( t, "email", m_values.email );
194 if( m_fields & FieldAddress )
195 new Tag( t, "address", m_values.address );
196 if( m_fields & FieldCity )
197 new Tag( t, "city", m_values.city );
198 if( m_fields & FieldState )
199 new Tag( t, "state", m_values.state );
200 if( m_fields & FieldZip )
201 new Tag( t, "zip", m_values.zip );
202 if( m_fields & FieldPhone )
203 new Tag( t, "phone", m_values.phone );
204 if( m_fields & FieldUrl )
205 new Tag( t, "url", m_values.url );
206 if( m_fields & FieldDate )
207 new Tag( t, "date", m_values.date );
208 if( m_fields & FieldMisc )
209 new Tag( t, "misc", m_values.misc );
210 if( m_fields & FieldText )
211 new Tag( t, "text", m_values.text );
212 }
213
214 return t;
215 }
216 // ---- ~Registration::Query ----
217
218 // ---- Registration ----
220 : m_parent( parent ), m_to( to ), m_registrationHandler( 0 )
221 {
222 init();
223 }
224
226 : m_parent( parent ), m_registrationHandler( 0 )
227 {
228 init();
229 }
230
231 void Registration::init()
232 {
233 if( m_parent )
234 {
235 m_parent->registerIqHandler( this, ExtRegistration );
236 m_parent->registerStanzaExtension( new Query() );
237 }
238 }
239
241 {
242 if( m_parent )
243 {
244 m_parent->removeIqHandler( this, ExtRegistration );
245 m_parent->removeIDHandler( this );
247 }
248 }
249
251 {
252 if( !m_parent || m_parent->state() != StateConnected )
253 return;
254
255 IQ iq( IQ::Get, m_to );
256 iq.addExtension( new Query() );
257 m_parent->send( iq, this, FetchRegistrationFields );
258 }
259
260 bool Registration::createAccount( int fields, const RegistrationFields& values )
261 {
262 std::string username;
263 if( !m_parent || !prep::nodeprep( values.username, username ) )
264 return false;
265
266 IQ iq( IQ::Set, m_to );
267 iq.addExtension( new Query( fields, values ) );
268 m_parent->send( iq, this, CreateAccount );
269
270 return true;
271 }
272
274 {
275 if( !m_parent || !form )
276 return;
277
278 IQ iq( IQ::Set, m_to );
279 iq.addExtension( new Query( form ) );
280 m_parent->send( iq, this, CreateAccount );
281 }
282
284 {
285 if( !m_parent || !m_parent->authed() )
286 return;
287
288 IQ iq( IQ::Set, m_to );
289 iq.addExtension( new Query( true ) );
290 m_parent->send( iq, this, RemoveAccount );
291 }
292
293 void Registration::changePassword( const std::string& username, const std::string& password )
294 {
295 if( !m_parent || !m_parent->authed() || username.empty() )
296 return;
297
298 int fields = FieldUsername | FieldPassword;
300 rf.username = username;
301 rf.password = password;
302 createAccount( fields, rf );
303 }
304
306 {
307 m_registrationHandler = rh;
308 }
309
311 {
312 m_registrationHandler = 0;
313 }
314
315 void Registration::handleIqID( const IQ& iq, int context )
316 {
317 if( !m_registrationHandler )
318 return;
319
320 if( iq.subtype() == IQ::Result )
321 {
322 switch( context )
323 {
324 case FetchRegistrationFields:
325 {
326 const Query* q = iq.findExtension<Query>( ExtRegistration );
327 if( !q )
328 return;
329
330 if( q->registered() )
331 m_registrationHandler->handleAlreadyRegistered( iq.from() );
332
333 if( q->form() )
334 m_registrationHandler->handleDataForm( iq.from(), *(q->form()) );
335
336 if( q->oob() )
337 m_registrationHandler->handleOOB( iq.from(), *(q->oob()) );
338
339 m_registrationHandler->handleRegistrationFields( iq.from(), q->fields(), q->instructions() );
340 break;
341 }
342
343 case CreateAccount:
344 case ChangePassword:
345 case RemoveAccount:
346 m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationSuccess );
347 break;
348 }
349 }
350 else if( iq.subtype() == IQ::Error )
351 {
352 const Error* e = iq.error();
353 if( !e )
354 return;
355
356 switch( e->error() )
357 {
359 m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationConflict );
360 break;
362 m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationNotAcceptable );
363 break;
365 m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationBadRequest );
366 break;
368 m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationForbidden );
369 break;
371 m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationRequired );
372 break;
374 m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationUnexpectedRequest );
375 break;
377 m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationNotAuthorized );
378 break;
380 m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationNotAllowed );
381 break;
383 m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationConstraint );
384 break;
385 default:
386 m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationUnknownError );
387 break;
388
389 }
390 }
391
392 }
393
394}
This is the common base class for a Jabber/XMPP Client and a Jabber Component.
Definition clientbase.h:79
ConnectionState state() const
void removeIqHandler(IqHandler *ih, int exttype)
void removeIDHandler(IqHandler *ih)
bool removeStanzaExtension(int ext)
void send(Tag *tag)
void registerIqHandler(IqHandler *ih, int exttype)
void registerStanzaExtension(StanzaExtension *ext)
bool authed() const
Definition clientbase.h:290
An abstraction of a XEP-0004 Data Form.
Definition dataform.h:57
A stanza error abstraction implemented as a StanzaExtension.
Definition error.h:35
StanzaError error() const
Definition error.h:75
An abstraction of an IQ stanza.
Definition iq.h:34
IqType subtype() const
Definition iq.h:74
@ Set
Definition iq.h:46
@ Error
Definition iq.h:49
@ Result
Definition iq.h:48
@ Get
Definition iq.h:45
An abstraction of a JID.
Definition jid.h:31
This is an abstraction of a jabber:x:oob namespace element or a jabber:iq:oob namespace element as sp...
Definition oob.h:36
A virtual interface that receives events from an Registration object.
virtual void handleDataForm(const JID &from, const DataForm &form)=0
virtual void handleAlreadyRegistered(const JID &from)=0
virtual void handleOOB(const JID &from, const OOB &oob)=0
virtual void handleRegistrationResult(const JID &from, RegistrationResult regResult)=0
virtual void handleRegistrationFields(const JID &from, int fields, std::string instructions)=0
A wrapping class for the XEP-0077 <query> element.
const DataForm * form() const
const OOB * oob() const
virtual const std::string & filterString() const
const std::string & instructions() const
virtual Tag * tag() const
void changePassword(const std::string &username, const std::string &password)
virtual void handleIqID(const IQ &iq, int context)
void registerRegistrationHandler(RegistrationHandler *rh)
bool createAccount(int fields, const RegistrationFields &values)
Registration(ClientBase *parent, const JID &to)
This class abstracts a stanza extension, which is usually an XML child element in a specific namespac...
void addExtension(const StanzaExtension *se)
Definition stanza.cpp:52
const Error * error() const
Definition stanza.cpp:47
const JID & from() const
Definition stanza.h:51
const StanzaExtension * findExtension(int type) const
Definition stanza.cpp:57
This is an abstraction of an XML element.
Definition tag.h:47
const std::string & name() const
Definition tag.h:394
const std::string xmlns() const
Definition tag.cpp:543
void addChild(Tag *child)
Definition tag.cpp:424
const TagList & children() const
Definition tag.cpp:510
bool setXmlns(const std::string &xmlns, const std::string &prefix=EmptyString)
Definition tag.cpp:522
bool nodeprep(const std::string &node, std::string &out)
Definition prep.cpp:59
The namespace for the gloox library.
Definition adhoc.cpp:28
std::list< Tag * > TagList
Definition tag.h:31
@ RegistrationUnknownError
@ RegistrationUnexpectedRequest
@ RegistrationNotAuthorized
@ RegistrationNotAcceptable
const std::string XMLNS_X_OOB
Definition gloox.cpp:51
const std::string XMLNS_REGISTER
Definition gloox.cpp:41
const std::string XMLNS_X_DATA
Definition gloox.cpp:49
@ StanzaErrorResourceConstraint
Definition gloox.h:934
@ StanzaErrorNotAllowed
Definition gloox.h:904
@ StanzaErrorForbidden
Definition gloox.h:884
@ StanzaErrorConflict
Definition gloox.h:878
@ StanzaErrorRegistrationRequired
Definition gloox.h:924
@ StanzaErrorNotAuthorized
Definition gloox.h:906
@ StanzaErrorUnexpectedRequest
Definition gloox.h:945
@ StanzaErrorBadRequest
Definition gloox.h:874
@ StanzaErrorNotAcceptable
Definition gloox.h:900
@ ExtRegistration
@ StateConnected
Definition gloox.h:644