Not logged in. · Lost password · Register
Forum: agsXMPP RSS
Avatar
dave-v #1
Member since Feb 2011 · 8 posts
Group memberships: Members
Show profile · Link to this post
Subject: Account Registration
Hi. 

Based on the sample MiniClient, I've been looking at account registration and have two questions.

Firstly, to detect registration failures I have added the XmppCon_OnRegisterError event. Within this event handler I've been trying to detect the error code from the element passed, but I've been totally failed to cast the element into anything that allows me to view the error fields.
I'd be greatful if you could explain to handle the Element passed to the even handler to extract the error.

Secondly, I've been trying to process the display the registration form returned by the server prior to requesting the login.  Although I can catch this using the OnRegisterInformation event the SDK is automatically requesting the login before I can display the information to the user.  Please can you suggest why this is.

Many thanks

Dave
Avatar
Alex #2
Member since Feb 2003 · 4297 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Quote by dave-v:
Firstly, to detect registration failures I have added the XmppCon_OnRegisterError event. Within this event handler I've been trying to detect the error code from the element passed, but I've been totally failed to cast the element into anything that allows me to view the error fields.
I'd be greatful if you could explain to handle the Element passed to the even handler to extract the error.

can yo please post the debug xml of the response and the reply. Then I can see which error your server sends and post the needed code here. Because there is a new XMPP style and old Jabber style errors, and I need to know which one your server sends.

Quote by dave-v:
Secondly, I've been trying to process the display the registration form returned by the server prior to requesting the login.  Although I can catch this using the OnRegisterInformation event the SDK is automatically requesting the login before I can display the information to the user.  Please can you suggest why this is.
In the OnRegisterInformation event there should be all info by the server required for the registration. There are again 2 protocols which are still in use by different server implementations. There is the old jabber:iq:register with the simple tags for the info, and there is the xdata registration form. When your server sends xdata you can fetch the xdata and display it with the agsXMPP.ui component in your user interface. In agsXMPP.ui there is a control for display and submit xdata forms.

Does this help?

Alex
Avatar
dave-v #3
Member since Feb 2011 · 8 posts
Group memberships: Members
Show profile · Link to this post
Hi Alex.

I've been using both eJabberd and Openfire, and the I've pasted the XML debug for both of them below.  In this example they both return a 409 error as the user name already exists.  I can trap the error response, but I'm having problems extracting information from the response.

eJabberd:
SEND: <iq id="agsXMPP_5" type="get" to="nowiresemail.com">
    <query xmlns="jabber:iq:register" />
    </iq>
RECV: <iq xmlns="jabber:client" from="nowiresemail.com" type="result" id="agsXMPP_5">
    <query xmlns="jabber:iq:register">
    <instructions>Choose a username and password to register with this server</instructions>
    <username /><password />
    </query></iq>
SEND: <iq type="set" id="agsXMPP_6" to="nowiresemail.com">
    <query xmlns="jabber:iq:register">
    <username>joe</username>
    <password>password</password>
    </query></iq>
RECV: <iq xmlns="jabber:client" from="nowiresemail.com" type="error" id="agsXMPP_6">
    <query xmlns="jabber:iq:register">
    <username>joe</username>
    <password>password</password></query>
    <error code="409" type="cancel"><conflict xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
    </error></iq>

   
Openfire:
SEND: <iq id="agsXMPP_3" type="get" to="nowiresemail.com">
    <query xmlns="jabber:iq:register" />
    </iq>
RECV: <iq xmlns="jabber:client" from="nowiresemail.com" type="result" id="agsXMPP_3">
    <query xmlns="jabber:iq:register">
    <username /><password /><email /><name />
    <x xmlns="jabber:x:data" type="form">
    <title>XMPP Client Registration</title>
    <instructions>Please provide the following information</instructions>
    <field type="hidden" var="FORM_TYPE">
    <value>jabber:iq:register</value></field>
    <field label="Username" var="username" type="text-single"><required /></field>
    <field label="Full name" var="name" type="text-single" />
    <field label="Email" var="email" type="text-single" />
    <field label="Password" var="password" type="text-private"><required />
    </field></x></query></iq>
SEND: <iq type="set" id="agsXMPP_4" to="nowiresemail.com">
    <query xmlns="jabber:iq:register">
    <username>joe</username><password>password</password>
    </query></iq>
RECV: <iq xmlns="jabber:client" from="nowiresemail.com" to="nowiresemail.com/d2fe6caf" type="error" id="agsXMPP_4">
    <query xmlns="jabber:iq:register"><username>joe</username>
    <password>password</password></query>
    <error code="409" type="cancel"><conflict xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
    </error></iq>


On the second point, I understand there are the two protocols, as demonstrated by the eJabberd and Openfire debug XML above.   To make use of any data the server returns I must therefore:
- create a connection with the RegisterAccount set to true;
- trap the reply with the OnRegistrationInformation event and display a form to the user, using x.data if available;
- send an iq set to the server requesting creatation of the user account.
If you can confirm this is the algorithm I should be following I'll re-write my code and try again.

Thanks for you assistance

Dave
Avatar
Alex #4
Member since Feb 2003 · 4297 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
In reply to post #2
here is an example how to get and evaluate the error object.

  1. agsXMPP.protocol.client.Error err = iq.SelectSingleElement<agsXMPP.protocol.client.Error>();
  2. if (err.Code == ErrorCode.Conflict)
  3. {
  4.    //add your code here
  5. }

Quote by dave-v:
On the second point, I understand there are the two protocols, as demonstrated by the eJabberd and Openfire debug XML above.   To make use of any data the server returns I must therefore:
- create a connection with the RegisterAccount set to true;
- trap the reply with the OnRegistrationInformation event and display a form to the user, using x.data if available;
- send an iq set to the server requesting creatation of the user account.
If you can confirm this is the algorithm I should be following I'll re-write my code and try again.

your Openfire supports both, old Jabber style and new xdata registration. You ejabberd supports only the old jabber style registration.
If you only work with this 2 servers then easiest is to use only old jabber style registration. In this case only the folling code is needed to build the registration Iq.

  1. RegisterIq regIq = new RegisterIq();
  2.  
  3. regIq.Id = iq.Id;
  4. regIq.To = iq.From;
  5. regIq.Type = IqType.set;
  6. regIq.Query.Username = "user";
  7. regIq.Query.Password = "secret";
  8.  
  9. xmppCon.Send(regIq);

Quote by dave-v:
Thanks for you assistance

you are welcome.

Alex
Avatar
dave-v #5
Member since Feb 2011 · 8 posts
Group memberships: Members
Show profile · Link to this post
Thanks for that - everything worked a treat.

I think I'm begining to understand the SDK more now   :-)

Dave
Avatar
dave-v #6
Member since Feb 2011 · 8 posts
Group memberships: Members
Show profile · Link to this post
Hi Alex.

I think I spole too soon about understanding the SDK - I'm still having problems with registration!

I'm opening a connection with RegisterAccount set to true, no user name or password are set, but with the other settings as for MiniClient.frmLogin.cmsLogin_Click().

I trap the XmppCon_OnRegisterInformation event, which is coded as follows:
  1.         private void XmppCon_OnRegisterInformation(object sender, RegisterEventArgs args)
  2.         {
  3.             RegisterIq regIq = new RegisterIq();
  4.                      
  5.             regIq.To = XmppCon.Server;
  6.             regIq.Type = IqType.set;
  7.             regIq.Query.Username = "user";
  8.             regIq.Query.Password = "secret";
  9.  
  10.             XmppCon.Send(regIq);
  11.         }

However, what I see are two registration requests being sent, as shown in the XML debug below.

SEND: <iq id="agsXMPP_1" type="get" to="nowiresemail.com">
    <query xmlns="jabber:iq:register" />
    </iq>
RECV: <iq xmlns="jabber:client" from="nowiresemail.com" type="result" id="agsXMPP_1">
    <query xmlns="jabber:iq:register">
    <instructions>Choose a username and password to register with this server</instructions>
    <username />
    <password />
    </query></iq>
SEND: <iq id="agsXMPP_2" to="nowiresemail.com" type="set">
    <query xmlns="jabber:iq:register">
    <username>user</username>
    <password>secret</password>
    </query></iq>
SEND: <iq type="set" id="agsXMPP_3" to="nowiresemail.com">
    <query xmlns="jabber:iq:register">
    <username />
    <password />
    </query></iq>
RECV: <iq xmlns="jabber:client" from="nowiresemail.com" type="error" id="agsXMPP_2">
    <query xmlns="jabber:iq:register">
    <username>user</username>
    <password>secret</password>
    </query>
    <error code="500" type="wait">
    <resource-constraint xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
    <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">Users are not allowed to register accounts so quickly</text>
    </error></iq>
RECV: <iq xmlns="jabber:client" from="nowiresemail.com" type="error" id="agsXMPP_3">
    <query xmlns="jabber:iq:register">
    <username />
    <password />
    </query>
    <error code="400" type="modify"><bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" /></error></iq>

One of these requests is being generated by the code in XmppCon_OnRegisterInformation and a second being generated automatically. (I've checked my XmppCon_OnIq handler and that is not doing anything).

I've tried all sorts of things, including setting RegisterEventArgs args.Auto to false in XmppCon_OnRegisterInformation, but this resulted in the contents of the previously received iq result being returned to the server.  I can also set XmppCon.Username and Password in the event handler which sets the values in the automatic request, but the request still sent immediately, so I can't prompt the user to enter any data.

Have you any suggestions as to how I can prevent the generation of the second object request?

Many thanks
Dave
Avatar
Alex #7
Member since Feb 2003 · 4297 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
sorry for my confusing response. I only wanted to show some examples how to work with the objects in agsXMPP.
When RegisterAccount is true then agsXMPP tries to register the account automatically. After successful registration it tries to login with the new account in the same session. You should provide a username and password with your session.

The OnRegisterInformation occurs before the RegisterIq of type set gets sent to the server. This event is there because with some server you can enter additional information for the registration. And you can get the XData form here and present it to your user in the GUI. In your case registration should work even when you do nothing in the OnRegisterInformation event.

Also the following code should work with both your servers:

  1. private void xmppClient_OnRegisterInformation(object sender, RegisterEventArgs e)
  2. {
  3.     a.Auto = false;
  4.    
  5.     e.Register.RemoveAll<Data>(); // removes the data form
  6.     e.Register.Username = xmppClient.Username;
  7.     e.Register.Password = xmppClient.Password;
  8. }

You modify only the Register object here which gets sent to the server in the Iq. You also can replace the complete Register object with a new one. Let me know if this helps.

Alex
Avatar
dave-v #8
Member since Feb 2011 · 8 posts
Group memberships: Members
Show profile · Link to this post
Hi Alex.

Thanks for clarifying when xmppClient_OnRegisterInformation is called and the use of RegisterEventArgs.Auto. After removing the data form I can successfully set the user name and password (although I think agsXMPP requries RemoveAllChildNodes rather than RemoveAll).

To offer the XData from xmppClient_OnRegisterInformation to a user I need to invoke a new UI thread.  As soon as this is started execution of the current thread continues, sending the RegisterIq of type set out to the server.  I can add some thread synchronisation to prevent this, but I was hoping for a simpler option in agsXMPP.

I guess an alternative solution would be to start the server connection as usual, but halt it prior to the Challenge /Reponse authorisation.  At this point I could send out the RegisterIq of type get and then everything is under my control.

Do you see my problem?

Dave
Avatar
Alex #9
Member since Feb 2003 · 4297 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Yes I see your problem, I guess the easiest way is to block the OnRegisterInformation event with some thread synchro.
Avatar
Alex #10
Member since Feb 2003 · 4297 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
just a side note:
Most of our users don't use account creation of XMPP streams. Because this opens also the doors to spammers. If you have a SQL backend to your XMPP server then its much easier to create to account directly in the sql database. For most servers this is only one simple INSERT to the database.
Avatar
dave-v #11
Member since Feb 2011 · 8 posts
Group memberships: Members
Show profile · Link to this post
Yes I see your problem, I guess the easiest way is to block the OnRegisterInformation event with some thread synchro.

OK, that I can handle - I just wanted to be sure I wasn't doing something silly with the SDK. 

just a side note:
Most of our users don't use account creation of XMPP streams. Because this opens also the doors to spammers. If you have a SQL backend to your XMPP server then its much easier to create to account directly in the sql database. For most servers this is only one simple INSERT to the database.

Yes, I've read about the problems.  For now I'm just experimenting in a closed network, but if it is ever realised as a full product then I suspect
that inband registration will be a requirement of the system.

Thanks for your assistance.

Dave
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please enter the word from the image into the text field below. (Type the letters only, lower case is okay.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters:
Forum: agsXMPP RSS