Login without setting the presence to available

I would like to do a login without setting the presence to available. The easyest way to do this would be to add an other login function, like the one submited below, in the XMPPConnection class.

Is there any chance to add this function in the next release? Or do you have a proposal how i shoud do this best. I tried to create a subclass of the XMPPConnection class… but some essential variables are private.

/**

  • Logs in to the server using the strongest authentication mode supported by

  • the server, then set our presence to available if setAvailable Flag is true.

  • If more than five seconds elapses in each step of the authentication process

  • without a response from the server, or if an error occurs, a XMPPException

  • will be thrown.

  • @param username the username.

  • @param password the password.

  • @param resource the resource.

  • @param setAvailable if we want to set our Presence to AVAILABLE

  • @throws XMPPException if an error occurs.

  • @throws IllegalStateException if not connected to the server, or already logged in

  • to the serrver.

*/

public synchronized void login(String username, String password, String resource, boolean setAvailable)

throws XMPPException {

if (!isConnected()) {

throw new IllegalStateException(“Not connected to server.”);

}

if (authenticated) {

throw new IllegalStateException(“Already logged in to server.”);

}

// If we send an authentication packet in “get” mode with just the username,

// the server will return the list of authentication protocols it supports.

Authentication discoveryAuth = new Authentication();

discoveryAuth.setType(IQ.Type.GET);

discoveryAuth.setUsername(username);

PacketCollector collector =

packetReader.createPacketCollector(new PacketIDFilter(discoveryAuth.getPacketID()));

// Send the packet

packetWriter.sendPacket(discoveryAuth);

// Wait up to a certain number of seconds for a response from the server.

IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());

if (response == null) {

throw new XMPPException(“No response from the server.”);

}

// If the server replied with an error, throw an exception.

else if (response.getType() == IQ.Type.ERROR) {

throw new XMPPException(response.getError());

}

// Otherwise, no error so continue processing.

Authentication authTypes = (Authentication) response;

collector.cancel();

// Now, create the authentication packet we’'ll send to the server.

Authentication auth = new Authentication();

auth.setUsername(username);

// Figure out if we should use digest or plain text authentication.

if (authTypes.getDigest() != null) {

auth.setDigest(connectionID, password);

}

else if (authTypes.getPassword() != null) {

auth.setPassword(password);

}

else {

throw new XMPPException(“Server does not support compatible authentication mechanism.”);

}

auth.setResource(resource);

collector = packetReader.createPacketCollector(new PacketIDFilter(auth.getPacketID()));

// Send the packet.

packetWriter.sendPacket(auth);

// Wait up to a certain number of seconds for a response from the server.

response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());

if (response == null) {

throw new XMPPException(“Authentication failed.”);

}

else if (response.getType() == IQ.Type.ERROR) {

throw new XMPPException(response.getError());

}

// Set the user.

if (response.getTo() != null) {

this.user = response.getTo();

}

else {

this.user = username + “@” + this.host;

if (resource != null) {

this.user += “/” + resource;

}

}

// We’'re done with the collector, so explicitly cancel it.

collector.cancel();

// Create the roster.

this.roster = new Roster(this);

roster.reload();

// Check Flag

if(setAvailable){

// Set presence to online.

packetWriter.sendPacket(new Presence(Presence.Type.AVAILABLE));

}

// Indicate that we’'re now authenticated.

authenticated = true;

anonymous = false;

// If debugging is enabled, change the the debug window title to include the

// name we are now logged-in as.

// If DEBUG_ENABLED was set to true AFTER the connection was created the debugger

// will be null

if (DEBUG_ENABLED && debugger != null) {

debugger.userHasLogged(user);

}

}

Message was edited by:

Stefan Kaeser

Stefan,

We’'d be happy to add this functionality if you can provide a bit more information about your use-case. In what case would you not set your presence to available? Are you looking for something like JEP-0126? (http://www.jabber.org/jeps/jep-0126.html)

Regards,

Matt

Hi matt

We are using jabber as messaging plattform in our framework. Now what i need, is to manipulate roster entry’'s of other users. I do this while the other user may be loged in. I connect and do the login without setting the presence to available. So i can manipulate the roster whitout getting stored or new messages from the server and nobody can see that i am online.

To do is i can not use the standard login function b/c the normal login function always sets the presence to available (sends a presence packet) and thats why i asked for a new login function which does not send a presence packet.

I did not check all the JEP’‘s and RFC’‘s maybe some server do not support loging in without setting the presence?! But it works with jabberd 1.4 and 2.0 and i think it should not get any problems with other jabber server’'s.

greets

Stefan

I have a use case exactly like that. I was working on a program which logs into two servers and copies the roster from one to the other. But setting available also destroys the messages which used to be on the queue.

I suppose that using Flexible Message Retrieval or negative priority would avoid the flood of messages, but there are other problems (e.g. users trying to talk to the bot.)

It would almost be better if Smack had separated the function of logging in from the function of becoming available.