gloox  0.9.9.12
registration.cpp
1 /*
2  Copyright (c) 2005-2008 by Jakob Schroeter <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 "prep.h"
19 #include "oob.h"
20 
21 namespace gloox
22 {
23 
25  : m_parent( parent ), m_to( to ), m_registrationHandler( 0 )
26  {
27  init();
28  }
29 
31  : m_parent( parent ), m_registrationHandler( 0 )
32  {
33  init();
34  }
35 
36  void Registration::init()
37  {
38  if( m_parent )
39  m_parent->registerIqHandler( this, XMLNS_REGISTER );
40  }
41 
43  {
44  if( m_parent )
45  {
46  m_parent->removeIqHandler( XMLNS_REGISTER );
47  m_parent->removeIDHandler( this );
48  }
49  }
50 
52  {
53  if( !m_parent || m_parent->state() != StateConnected )
54  return;
55 
56  const std::string& id = m_parent->getID();
57 
58  Tag *iq = new Tag( "iq" );
59  if( m_to )
60  iq->addAttribute( "to", m_to.full() );
61  iq->addAttribute( "type", "get" );
62  iq->addAttribute( "id", id );
63  Tag *q = new Tag( iq, "query" );
64  q->addAttribute( "xmlns", XMLNS_REGISTER );
65 
66  m_parent->trackID( this, id, FetchRegistrationFields );
67  m_parent->send( iq );
68  }
69 
70  void Registration::createAccount( int fields, const RegistrationFields& values )
71  {
72  if( !m_parent || m_parent->state() != StateConnected )
73  return;
74 
75  const std::string& id = m_parent->getID();
76 
77  Tag *iq = new Tag( "iq" );
78  if( m_to )
79  iq->addAttribute( "to", m_to.full() );
80  iq->addAttribute( "id", id );
81  iq->addAttribute( "type", "set" );
82  Tag *q = new Tag( iq, "query" );
83  q->addAttribute( "xmlns", XMLNS_REGISTER );
84 
85  if( fields & FieldUsername )
86  new Tag( q, "username", prep::nodeprep( values.username ) );
87  if( fields & FieldNick )
88  new Tag( q, "nick", values.nick );
89  if( fields & FieldPassword )
90  new Tag( q, "password", values.password );
91  if( fields & FieldName )
92  new Tag( q, "name", values.name );
93  if( fields & FieldFirst )
94  new Tag( q, "first", values.first );
95  if( fields & FieldLast )
96  new Tag( q, "last", values.last );
97  if( fields & FieldEmail )
98  new Tag( q, "email", values.email );
99  if( fields & FieldAddress )
100  new Tag( q, "address", values.address );
101  if( fields & FieldCity )
102  new Tag( q, "city", values.city );
103  if( fields & FieldState )
104  new Tag( q, "state", values.state );
105  if( fields & FieldZip )
106  new Tag( q, "zip", values.zip );
107  if( fields & FieldPhone )
108  new Tag( q, "phone", values.phone );
109  if( fields & FieldUrl )
110  new Tag( q, "url", values.url );
111  if( fields & FieldDate )
112  new Tag( q, "date", values.date );
113  if( fields & FieldMisc )
114  new Tag( q, "misc", values.misc );
115  if( fields & FieldText )
116  new Tag( q, "text", values.text );
117 
118  m_parent->trackID( this, id, CreateAccount );
119  m_parent->send( iq );
120  }
121 
123  {
124  if( !m_parent || m_parent->state() != StateConnected )
125  return;
126 
127  const std::string& id = m_parent->getID();
128 
129  Tag *iq = new Tag( "iq" );
130  if( m_to )
131  iq->addAttribute( "to", m_to.full() );
132  iq->addAttribute( "id", id );
133  iq->addAttribute( "type", "set" );
134  Tag *q = new Tag( iq, "query" );
135  q->addAttribute( "xmlns", XMLNS_REGISTER );
136  q->addChild( form.tag() );
137 
138  m_parent->trackID( this, id, CreateAccount );
139  m_parent->send( iq );
140  }
141 
143  {
144  if( !m_parent || !m_parent->authed() )
145  return;
146 
147  const std::string& id = m_parent->getID();
148 
149  Tag *iq = new Tag( "iq" );
150  if( m_to )
151  iq->addAttribute( "to", m_to.full() );
152  iq->addAttribute( "type", "set" );
153  iq->addAttribute( "id", id );
154  iq->addAttribute( "from", m_parent->jid().full() );
155  Tag *q = new Tag( iq, "query" );
156  q->addAttribute( "xmlns", XMLNS_REGISTER );
157  new Tag( q, "remove" );
158 
159  m_parent->trackID( this, id, RemoveAccount );
160  m_parent->send( iq );
161  }
162 
163  void Registration::changePassword( const std::string& username, const std::string& password )
164  {
165  if( !m_parent || !m_parent->authed() )
166  return;
167 
168  const std::string& id = m_parent->getID();
169 
170  Tag *iq = new Tag( "iq" );
171  if( m_to )
172  iq->addAttribute( "to", m_to.full() );
173  iq->addAttribute( "type", "set" );
174  iq->addAttribute( "id", id );
175  Tag *q = new Tag( iq, "query" );
176  q->addAttribute( "xmlns", XMLNS_REGISTER );
177  new Tag( q, "username", username );
178  new Tag( q, "password", password );
179 
180  m_parent->trackID( this, id, ChangePassword );
181  m_parent->send( iq );
182  }
183 
185  {
186  m_registrationHandler = rh;
187  }
188 
190  {
191  m_registrationHandler = 0;
192  }
193 
194  bool Registration::handleIqID( Stanza* stanza, int context )
195  {
196  if( !m_registrationHandler )
197  return false;
198 
199  if( stanza->subtype() == StanzaIqResult )
200  {
201  switch( context )
202  {
203  case FetchRegistrationFields:
204  {
205  Tag *q = stanza->findChild( "query" );
206  if( !q )
207  return false;
208 
209  if( q->hasChild( "registered" ) )
210  {
211  m_registrationHandler->handleAlreadyRegistered( stanza->from() );
212  break;
213  }
214 
215  if( q->hasChild( "x", "xmlns", XMLNS_X_DATA ) )
216  {
217  DataForm form( q->findChild( "x", "xmlns", XMLNS_X_DATA ) );
218  m_registrationHandler->handleDataForm( stanza->from(), form );
219  }
220 
221  if( q->hasChild( "x", "xmlns", XMLNS_X_OOB ) )
222  {
223  OOB oob( q->findChild( "x", "xmlns", XMLNS_X_OOB ) );
224  m_registrationHandler->handleOOB( stanza->from(), oob );
225  }
226 
227  int fields = 0;
228  std::string instructions;
229 
230  if( q->hasChild( "username" ) )
231  fields |= FieldUsername;
232  if( q->hasChild( "nick" ) )
233  fields |= FieldNick;
234  if( q->hasChild( "password" ) )
235  fields |= FieldPassword;
236  if( q->hasChild( "name" ) )
237  fields |= FieldName;
238  if( q->hasChild( "first" ) )
239  fields |= FieldFirst;
240  if( q->hasChild( "last" ) )
241  fields |= FieldLast;
242  if( q->hasChild( "email" ) )
243  fields |= FieldEmail;
244  if( q->hasChild( "address" ) )
245  fields |= FieldAddress;
246  if( q->hasChild( "city" ) )
247  fields |= FieldCity;
248  if( q->hasChild( "state" ) )
249  fields |= FieldState;
250  if( q->hasChild( "zip" ) )
251  fields |= FieldZip;
252  if( q->hasChild( "phone" ) )
253  fields |= FieldPhone;
254  if( q->hasChild( "url" ) )
255  fields |= FieldUrl;
256  if( q->hasChild( "date" ) )
257  fields |= FieldDate;
258  if( q->hasChild( "misc" ) )
259  fields |= FieldMisc;
260  if( q->hasChild( "text" ) )
261  fields |= FieldText;
262  if( q->hasChild( "instructions" ) )
263  instructions = q->findChild( "instructions" )->cdata();
264 
265  m_registrationHandler->handleRegistrationFields( stanza->from(), fields, instructions );
266  break;
267  }
268 
269  case CreateAccount:
270  m_registrationHandler->handleRegistrationResult( stanza->from(), RegistrationSuccess );
271  break;
272 
273  case ChangePassword:
274  m_registrationHandler->handleRegistrationResult( stanza->from(), RegistrationSuccess );
275  break;
276 
277  case RemoveAccount:
278  m_registrationHandler->handleRegistrationResult( stanza->from(), RegistrationSuccess );
279  break;
280  }
281  }
282  else if( stanza->subtype() == StanzaIqError )
283  {
284  Tag *e = stanza->findChild( "error" );
285 
286  if( !e )
287  return false;
288 
289  if( e->hasChild( "conflict" ) || e->hasAttribute( "code", "409" ) )
290  m_registrationHandler->handleRegistrationResult( stanza->from(), RegistrationConflict );
291  else if( e->hasChild( "not-acceptable" ) || e->hasAttribute( "code", "406" ) )
292  m_registrationHandler->handleRegistrationResult( stanza->from(), RegistrationNotAcceptable );
293  else if( e->hasChild( "bad-request" ) || e->hasAttribute( "code", "400" ) )
294  m_registrationHandler->handleRegistrationResult( stanza->from(), RegistrationBadRequest );
295  else if( e->hasChild( "forbidden" ) || e->hasAttribute( "code", "403" ) )
296  m_registrationHandler->handleRegistrationResult( stanza->from(), RegistrationForbidden );
297  else if( e->hasChild( "registration-required" ) || e->hasAttribute( "code", "407" ) )
298  m_registrationHandler->handleRegistrationResult( stanza->from(), RegistrationRequired );
299  else if( e->hasChild( "unexpected-request" ) || e->hasAttribute( "code", "400" ) )
300  m_registrationHandler->handleRegistrationResult( stanza->from(), RegistrationUnexpectedRequest );
301  else if( e->hasChild( "not-authorized" ) || e->hasAttribute( "code", "401" ) )
302  m_registrationHandler->handleRegistrationResult( stanza->from(), RegistrationNotAuthorized );
303  else if( e->hasChild( "not-allowed" ) || e->hasAttribute( "code", "405" ) )
304  m_registrationHandler->handleRegistrationResult( stanza->from(), RegistrationNotAllowed );
305  else
306  m_registrationHandler->handleRegistrationResult( stanza->from(), RegistrationUnknownError );
307  }
308 
309  return false;
310  }
311 
312 }