registration.cpp

00001 /*
00002   Copyright (c) 2005-2009 by Jakob Schroeter <js@camaya.net>
00003   This file is part of the gloox library. http://camaya.net/gloox
00004 
00005   This software is distributed under a license. The full license
00006   agreement can be found in the file LICENSE in this distribution.
00007   This software may not be copied, modified, sold or distributed
00008   other than expressed in the named license agreement.
00009 
00010   This software is distributed without any warranty.
00011 */
00012 
00013 
00014 #include "registration.h"
00015 
00016 #include "clientbase.h"
00017 #include "stanza.h"
00018 #include "error.h"
00019 #include "prep.h"
00020 #include "oob.h"
00021 
00022 namespace gloox
00023 {
00024 
00025   // Registration::Query ----
00026   Registration::Query::Query( DataForm* form )
00027     : StanzaExtension( ExtRegistration ), m_form( form ), m_fields( 0 ), m_oob( 0 ),
00028       m_del( false ), m_reg( false )
00029   {
00030   }
00031 
00032   Registration::Query::Query( bool del )
00033     : StanzaExtension( ExtRegistration ), m_form( 0 ), m_fields( 0 ), m_oob( 0 ), m_del( del ),
00034       m_reg( false )
00035   {
00036   }
00037 
00038   Registration::Query::Query( int fields, const RegistrationFields& values )
00039     : StanzaExtension( ExtRegistration ), m_form( 0 ), m_fields( fields ), m_values( values ),
00040       m_oob( 0 ), m_del( false ), m_reg( false )
00041   {
00042   }
00043 
00044   Registration::Query::Query( const Tag* tag )
00045     : StanzaExtension( ExtRegistration ), m_form( 0 ), m_fields( 0 ), m_oob( 0 ), m_del( false ),
00046       m_reg( false )
00047   {
00048     if( !tag || tag->name() != "query" || tag->xmlns() != XMLNS_REGISTER )
00049       return;
00050 
00051     const TagList& l = tag->children();
00052     TagList::const_iterator it = l.begin();
00053     for( ; it != l.end(); ++it )
00054     {
00055       const std::string& name = (*it)->name();
00056       if( name == "instructions" )
00057         m_instructions = (*it)->cdata();
00058       else if( name == "remove" )
00059         m_del = true;
00060       else if( name == "registered" )
00061         m_reg = true;
00062       else if( name == "username" )
00063       {
00064         m_fields |= FieldUsername;
00065         m_values.username = (*it)->cdata();
00066       }
00067       else if( name == "nick" )
00068       {
00069         m_fields |= FieldNick;
00070         m_values.nick = (*it)->cdata();
00071       }
00072       else if( name == "password" )
00073       {
00074         m_fields |= FieldPassword;
00075         m_values.password = (*it)->cdata();
00076       }
00077       else if( name == "name" )
00078       {
00079         m_fields |= FieldName;
00080         m_values.name = (*it)->cdata();
00081       }
00082       else if( name == "first" )
00083       {
00084         m_fields |= FieldFirst;
00085         m_values.first = (*it)->cdata();
00086       }
00087       else if( name == "last" )
00088       {
00089         m_fields |= FieldLast;
00090         m_values.last = (*it)->cdata();
00091       }
00092       else if( name == "email" )
00093       {
00094         m_fields |= FieldEmail;
00095         m_values.email = (*it)->cdata();
00096       }
00097       else if( name == "address" )
00098       {
00099         m_fields |= FieldAddress;
00100         m_values.address = (*it)->cdata();
00101       }
00102       else if( name == "city" )
00103       {
00104         m_fields |= FieldCity;
00105         m_values.city = (*it)->cdata();
00106       }
00107       else if( name == "state" )
00108       {
00109         m_fields |= FieldState;
00110         m_values.state = (*it)->cdata();
00111       }
00112       else if( name == "zip" )
00113       {
00114         m_fields |= FieldZip;
00115         m_values.zip = (*it)->cdata();
00116       }
00117       else if( name == "phone" )
00118       {
00119         m_fields |= FieldPhone;
00120         m_values.phone = (*it)->cdata();
00121       }
00122       else if( name == "url" )
00123       {
00124         m_fields |= FieldUrl;
00125         m_values.url = (*it)->cdata();
00126       }
00127       else if( name == "date" )
00128       {
00129         m_fields |= FieldDate;
00130         m_values.date = (*it)->cdata();
00131       }
00132       else if( name == "misc" )
00133       {
00134         m_fields |= FieldMisc;
00135         m_values.misc = (*it)->cdata();
00136       }
00137       else if( name == "text" )
00138       {
00139         m_fields |= FieldText;
00140         m_values.text = (*it)->cdata();
00141       }
00142       else if( !m_form && name == "x" && (*it)->xmlns() == XMLNS_X_DATA )
00143         m_form = new DataForm( (*it) );
00144       else if( !m_oob && name == "x" && (*it)->xmlns() == XMLNS_X_OOB )
00145         m_oob = new OOB( (*it) );
00146     }
00147   }
00148 
00149   Registration::Query::~Query()
00150   {
00151     delete m_form;
00152     delete m_oob;
00153   }
00154 
00155   const std::string& Registration::Query::filterString() const
00156   {
00157     static const std::string filter = "/iq/query[@xmlns='" + XMLNS_REGISTER + "']";
00158     return filter;
00159   }
00160 
00161   Tag* Registration::Query::tag() const
00162   {
00163     Tag* t = new Tag( "query" );
00164     t->setXmlns( XMLNS_REGISTER );
00165 
00166     if( !m_instructions.empty() )
00167       new Tag( t, "instructions", m_instructions );
00168 
00169     if ( m_reg )
00170       new Tag( t, "registered" );
00171 
00172     if( m_form )
00173       t->addChild( m_form->tag() );
00174     else if( m_oob )
00175       t->addChild( m_oob->tag() );
00176     else if( m_del )
00177       new Tag( t, "remove" );
00178     else if( m_fields )
00179     {
00180       if( m_fields & FieldUsername )
00181         new Tag( t, "username", m_values.username );
00182       if( m_fields & FieldNick )
00183         new Tag( t, "nick", m_values.nick );
00184       if( m_fields & FieldPassword )
00185         new Tag( t, "password", m_values.password );
00186       if( m_fields & FieldName )
00187         new Tag( t, "name", m_values.name );
00188       if( m_fields & FieldFirst )
00189         new Tag( t, "first", m_values.first );
00190       if( m_fields & FieldLast )
00191         new Tag( t, "last", m_values.last );
00192       if( m_fields & FieldEmail )
00193         new Tag( t, "email", m_values.email );
00194       if( m_fields & FieldAddress )
00195         new Tag( t, "address", m_values.address );
00196       if( m_fields & FieldCity )
00197         new Tag( t, "city", m_values.city );
00198       if( m_fields & FieldState )
00199         new Tag( t, "state", m_values.state );
00200       if( m_fields & FieldZip )
00201         new Tag( t, "zip", m_values.zip );
00202       if( m_fields & FieldPhone )
00203         new Tag( t, "phone", m_values.phone );
00204       if( m_fields & FieldUrl )
00205         new Tag( t, "url", m_values.url );
00206       if( m_fields & FieldDate )
00207         new Tag( t, "date", m_values.date );
00208       if( m_fields & FieldMisc )
00209         new Tag( t, "misc", m_values.misc );
00210       if( m_fields & FieldText )
00211         new Tag( t, "text", m_values.text );
00212     }
00213 
00214     return t;
00215   }
00216   // ---- ~Registration::Query ----
00217 
00218   // ---- Registration ----
00219   Registration::Registration( ClientBase* parent, const JID& to )
00220     : m_parent( parent ), m_to( to ), m_registrationHandler( 0 )
00221   {
00222     init();
00223   }
00224 
00225   Registration::Registration( ClientBase* parent )
00226   : m_parent( parent ), m_registrationHandler( 0 )
00227   {
00228     init();
00229   }
00230 
00231   void Registration::init()
00232   {
00233     if( m_parent )
00234     {
00235       m_parent->registerIqHandler( this, ExtRegistration );
00236       m_parent->registerStanzaExtension( new Query() );
00237     }
00238   }
00239 
00240   Registration::~Registration()
00241   {
00242     if( m_parent )
00243     {
00244       m_parent->removeIqHandler( this, ExtRegistration );
00245       m_parent->removeIDHandler( this );
00246       m_parent->removeStanzaExtension( ExtRegistration );
00247     }
00248   }
00249 
00250   void Registration::fetchRegistrationFields()
00251   {
00252     if( !m_parent || m_parent->state() != StateConnected )
00253       return;
00254 
00255     IQ iq( IQ::Get, m_to );
00256     iq.addExtension( new Query() );
00257     m_parent->send( iq, this, FetchRegistrationFields );
00258   }
00259 
00260   bool Registration::createAccount( int fields, const RegistrationFields& values )
00261   {
00262     std::string username;
00263     if( !m_parent || !prep::nodeprep( values.username, username ) )
00264       return false;
00265 
00266     IQ iq( IQ::Set, m_to );
00267     iq.addExtension( new Query( fields, values ) );
00268     m_parent->send( iq, this, CreateAccount );
00269 
00270     return true;
00271   }
00272 
00273   void Registration::createAccount( DataForm* form )
00274   {
00275     if( !m_parent || !form )
00276       return;
00277 
00278     IQ iq( IQ::Set, m_to );
00279     iq.addExtension( new Query( form ) );
00280     m_parent->send( iq, this, CreateAccount );
00281   }
00282 
00283   void Registration::removeAccount()
00284   {
00285     if( !m_parent || !m_parent->authed() )
00286       return;
00287 
00288     IQ iq( IQ::Set, m_to );
00289     iq.addExtension( new Query( true ) );
00290     m_parent->send( iq, this, RemoveAccount );
00291   }
00292 
00293   void Registration::changePassword( const std::string& username, const std::string& password )
00294   {
00295     if( !m_parent || !m_parent->authed() || username.empty() )
00296       return;
00297 
00298     int fields = FieldUsername | FieldPassword;
00299     RegistrationFields rf;
00300     rf.username = username;
00301     rf.password = password;
00302     createAccount( fields, rf );
00303   }
00304 
00305   void Registration::registerRegistrationHandler( RegistrationHandler* rh )
00306   {
00307     m_registrationHandler = rh;
00308   }
00309 
00310   void Registration::removeRegistrationHandler()
00311   {
00312     m_registrationHandler = 0;
00313   }
00314 
00315   void Registration::handleIqID( const IQ& iq, int context )
00316   {
00317     if( !m_registrationHandler )
00318       return;
00319 
00320     if( iq.subtype() == IQ::Result )
00321     {
00322       switch( context )
00323       {
00324         case FetchRegistrationFields:
00325         {
00326           const Query* q = iq.findExtension<Query>( ExtRegistration );
00327           if( !q )
00328             return;
00329 
00330           if( q->registered() )
00331             m_registrationHandler->handleAlreadyRegistered( iq.from() );
00332 
00333           if( q->form() )
00334             m_registrationHandler->handleDataForm( iq.from(), *(q->form()) );
00335 
00336           if( q->oob() )
00337             m_registrationHandler->handleOOB( iq.from(), *(q->oob()) );
00338 
00339           m_registrationHandler->handleRegistrationFields( iq.from(), q->fields(), q->instructions() );
00340           break;
00341         }
00342 
00343         case CreateAccount:
00344         case ChangePassword:
00345         case RemoveAccount:
00346           m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationSuccess );
00347           break;
00348       }
00349     }
00350     else if( iq.subtype() == IQ::Error )
00351     {
00352       const Error* e = iq.error();
00353       if( !e )
00354         return;
00355 
00356       switch( e->error() )
00357       {
00358         case StanzaErrorConflict:
00359           m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationConflict );
00360           break;
00361         case StanzaErrorNotAcceptable:
00362           m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationNotAcceptable );
00363           break;
00364         case StanzaErrorBadRequest:
00365           m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationBadRequest );
00366           break;
00367         case StanzaErrorForbidden:
00368           m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationForbidden );
00369           break;
00370         case StanzaErrorRegistrationRequired:
00371           m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationRequired );
00372           break;
00373         case StanzaErrorUnexpectedRequest:
00374           m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationUnexpectedRequest );
00375           break;
00376         case StanzaErrorNotAuthorized:
00377           m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationNotAuthorized );
00378           break;
00379         case StanzaErrorNotAllowed:
00380           m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationNotAllowed );
00381           break;
00382         default:
00383           m_registrationHandler->handleRegistrationResult( iq.from(), RegistrationUnknownError );
00384           break;
00385 
00386       }
00387     }
00388 
00389   }
00390 
00391 }

Generated by  doxygen 1.6.2