Thoughts on the registration process

In addition to GATE-146: How should the registration process in XEP-0100 interpreted? I’‘ve written a number of tests based on my interpretation of the XEP. I’‘m noticing a number of failures though, when I run those tests on the gateway plugin. I’'m listing them here. For your consideration

Following section 4.1.1.6, the transport should check the legacy credentials received for validity on the legacy domain, returning if that fails. The plugin however accepts any user/pass combination during registration.

Taking 4.1.1.9 into account, I would expect the transport to send out an subscription request, after the legacy credentials have been verified. The gateway plugin doesn’'t send out subscription requests though.

Going further on the same subject, I would expect the transport to accept and return subscription requests from previously registered users (section 9 and 10). Subscription requests addressed at transport components of the gateway plugin go unanswered though.

Trying to unregister with a malformed packet (XEP-0077, section 3.2, table 1) should return , but is accepted. That’'s easily fixed by adjusting BaseTransport like this:

@@ -554,6 +554,12 @@
             // this.convinceNotToLeave() ... kidding.
             IQ result = IQ.createResultIQ(packet); +             if (packet.getChildElement().elements().size() != 1) {
+                  result.setError(Condition.bad_request);
+                  reply.add(result);
+                  return reply;
+             }
+
             // Tell the end user the transport went byebye.
             Presence unavailable = new Presence(Presence.Type.unavailable);
             unavailable.setTo(from);

If a user tries to delete his registration, without being registered first, the XEP calls for a . The current plugin doesn’‘t even send back an error (but throws a only if the user isn’'t a member of the local XMPP domain). Two adjustments will fix this:

@@ -565,7 +571,7 @@
             }
             catch (UserNotFoundException e) {
                 Log.error("Error cleaning up contact list of: " + from);
-                result.setError(Condition.bad_request);
+                result.setError(Condition.registration_required);
             }              reply.add(result);
@@ -1331,6 +1345,9 @@
      */
     public void deleteRegistration(JID jid) throws UserNotFoundException {
         Collection<Registration> registrations = registrationManager.getRegistrations(jid, this.transportType);
+        if (registrations.isEmpty()) {
+             throw new UserNotFoundException("User wasn''t registered.");
+        }
         // For now, we''re going to have to just nuke all of these.  Sorry.
         for (Registration reg : registrations) {
             registrationManager.deleteRegistration(reg);

Hey, why isn’'t that last code block formatted?

I’‘ll speak on more of these in a bit, but let me say that at some level we are explicitly -not- following XEP-0100 to the T in an attempt to make things smoother. A subscription packet, for example, is not really necessary when we can just place the item in the user’‘s roster directly. Since we don’‘t care about folk that aren’'t on the same server, this is easy to do behind the scenes.

Parts of the process are a little weird though.

Also I have no idea why it wasn’'t block formatted. ;D

I’‘m not sure if this should be an issue, but if you’'re manipulating the roster directly, users that are not members of the domain hosting the transport are unable to make use of it.

Message was edited by: Guus

D’‘oh! Didn’'t I read or did you edit?

Actually it looks like I’'ve got some time to speak on this already, so:

Guus wrote:

In addition to GATE-146: How should the registration process in XEP-0100 interpreted? I’‘ve written a number of tests based on my interpretation of the XEP. I’‘m noticing a number of failures though, when I run those tests on the gateway plugin. I’'m listing them here. For your consideration

Following section 4.1.1.6, the transport should check the legacy credentials received for validity on the legacy domain, returning if that fails. The plugin however accepts any user/pass combination during registration.

GATE-178, I’‘ll look into it, but from my experience with PyAIMt and PyICQt, users get more upset of registration auto-logs them in before they are really showing as logged in. To check a username and password I actually have to log the user in and get some sort of success or failure, which can cause things like… oh… their friends will see them, try to IM them, and lose the message. Stuff like that. It’‘s one of those things that caused more harm than good at the time. The alternative, which I went with in the Pys and here, is that you tell the user their username and password is wrong when they actually go to log in and then instruct them to reregister with the correct username and password. It’'s a hard tradeoff to decide on.

Taking 4.1.1.9 into account, I would expect the transport to send out an subscription request, after the legacy credentials have been verified. The gateway plugin doesn’'t send out subscription requests though.

It doesn’‘t need to since it’‘s directly putting the item in the user’‘s roster. Subscription requests, again dealing with experience from the Pys, scare the crap out of users and confuse them. Also note that if I send a subscription request it’‘ll completely confuse the process whereby Spark can interact with the transports without having to have them in the user’'s roster. I used to send subscription requests and got complaints. Lots of them.

BTW, this is where my confusion comes on. There’‘s a note there about you can optionally (4.1.1.8) do the iq set for the roster item, but then you seem to “have” to do the subscription requests, which can end up causing the item to get in the roster anyway. So I kind of don’‘t see the point in 4.1.1.8 being optional. That’'s what I wanted to chat with Peter about a little to get that fleshed out in my head.

Note that XEP-0100 was written before there were many transports nor many thoughts of how to make things better.

There’‘s even a proposal floating around whereby the transports actually assume ownership over their piece of the user’‘s roster entirely. I’'d sure like to see that happen. It would love to see PyAIMt and PyICQt benefit.

Going further on the same subject, I would expect the transport to accept and return subscription requests from previously registered users (section 9 and 10). Subscription requests addressed at transport components of the gateway plugin go unanswered though.

This is one of the biggest complaints I ever see, the “subscription request flood” as it’‘s referred to. If I have 100 users on my ICQ list and I connect to ICQ via the plugin, it’'s a pain in the butt to then receive 100 subscription requests. Hence the glory of being able to do it on the backend.

Trying to unregister with a malformed packet (XEP-0077, section 3.2, table 1) should return , but is accepted. That’'s easily fixed by adjusting BaseTransport like this:

snip

Indeed. =) Applied this patch, thanks!

If a user tries to delete his registration, without being registered first, the XEP calls for a . The current plugin doesn’‘t even send back an error (but throws a only if the user isn’'t a member of the local XMPP domain). Two adjustments will fix this:

snip

Excellent, thanks! Applied. =)

Guus wrote:

I’‘m not sure if this should be an issue, but if you’'re manipulating the roster directly, users that are not members of the domain hosting the transport are unable to make use of it.

Message was edited by: Guus

D’‘oh! Didn’'t I read or did you edit?

;D I didn’’ edit. “Sometime in the future”, btw, I’‘d like to really sit down with some of the XMPP standards and try to work out a way for the world to be cleaner, but that’‘s not a 1.0 goal by any means. Anyway, basically I’‘d like to possibly make it so people off-server could register in the future. But I’'m keeping that out of my thought process for now. ;D

Is there a working copy of the revised XEP-0100 (as you use it) available somewhere? It would be useful place to base testing, development and discussion on the original XEP on.

jadestorm wrote:

GATE-178, I’‘ll look into it, but from my experience with PyAIMt and PyICQt, users get more upset of registration auto-logs them in before they are really showing as logged in. To check a username and password I actually have to log the user in and get some sort of success or failure, which can cause things like… oh… their friends will see them, try to IM them, and lose the message. Stuff like that. It’‘s one of those things that caused more harm than good at the time. The alternative, which I went with in the Pys and here, is that you tell the user their username and password is wrong when they actually go to log in and then instruct them to reregister with the correct username and password. It’'s a hard tradeoff to decide on.

I have to admit that we didn’'t do this either (for our network, we were able to check the credentials without logging in), but the XEP explains us to buffer translatable events until the registration process is complete. As any successful registration would cause a user to login eventually, would that be an option?

jadestorm wrote:

This is one of the biggest complaints I ever see, the “subscription request flood” as it’‘s referred to. If I have 100 users on my ICQ list and I connect to ICQ via the plugin, it’'s a pain in the butt to then receive 100 subscription requests. Hence the glory of being able to do it on the backend.

I was referring to subscription request sent to the transport directly, not to legacy users (that appear as nodes on the transport). Manipulating the roster directly circumvents the problem though.

Guus wrote:

Is there a working copy of the revised XEP-0100 (as you use it) available somewhere? It would be useful place to base testing, development and discussion on the original XEP on.

jadestorm wrote:

GATE-178, I’‘ll look into it, but from my experience with PyAIMt and PyICQt, users get more upset of registration auto-logs them in before they are really showing as logged in. To check a username and password I actually have to log the user in and get some sort of success or failure, which can cause things like… oh… their friends will see them, try to IM them, and lose the message. Stuff like that. It’‘s one of those things that caused more harm than good at the time. The alternative, which I went with in the Pys and here, is that you tell the user their username and password is wrong when they actually go to log in and then instruct them to reregister with the correct username and password. It’'s a hard tradeoff to decide on.

I have to admit that we didn’'t do this either (for our network, we were able to check the credentials without logging in), but the XEP explains us to buffer translatable events until the registration process is complete. As any successful registration would cause a user to login eventually, would that be an option?

Well, it’‘s actually not required for the transport to probe the user to see if they are actually logged on at the time, so they may -not- auto-log in. Off the top of my head I don’‘t recall, but I think Spark doesn’‘t force you to be logged in immediately. On top of that, it’'s possible to register without being logged in at the time (through the web interface) so that would get even more confusing.