diff --git a/source/org/jivesoftware/smack/XMPPConnection.java b/source/org/jivesoftware/smack/XMPPConnection.java index 710aa9652..f467dadc2 100644 --- a/source/org/jivesoftware/smack/XMPPConnection.java +++ b/source/org/jivesoftware/smack/XMPPConnection.java @@ -54,6 +54,7 @@ package org.jivesoftware.smack; import org.jivesoftware.smack.packet.*; import org.jivesoftware.smack.filter.*; +import org.jivesoftware.smack.util.StringUtils; import javax.swing.*; import java.net.*; @@ -111,10 +112,10 @@ public class XMPPConnection { protected Socket socket; String connectionID; - private String username = null; - private String resource = null; + private String user = null; private boolean connected = false; private boolean authenticated = false; + private boolean anonymous = false; private PacketWriter packetWriter; private PacketReader packetReader; @@ -196,28 +197,17 @@ public class XMPPConnection { } /** - * Returns the username that was used to login or null if not logged in yet. + * Returns the full XMPP address of the user that is logged in to the connection or + * null if not logged in yet. An XMPP address is in the form + * username@server/resource. * - * @return the username used to login. + * @return the full XMPP address of the user logged in. */ - public String getUsername() { + public String getUser() { if (!isAuthenticated()) { return null; } - return username; - } - - /** - * Returns the resource that was used to login or null if not logged in yet. - * If no resource was used to login, the default resource "Smack" will be returned. - * - * @return the resource used to login. - */ - public String getResource() { - if (!isAuthenticated()) { - return null; - } - return resource; + return user; } /** @@ -256,8 +246,6 @@ public class XMPPConnection { if (authenticated) { throw new IllegalStateException("Already logged in to server."); } - this.username = username; - this.resource = resource; // 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(); @@ -310,6 +298,17 @@ public class XMPPConnection { else if (response.getType() == IQ.Type.ERROR) { throw new XMPPException(response.getError()); } + // Set the user. + if (response.getTo() != null) { + this.user = response.getTo(); + } + else { + Authentication authResponse = (Authentication)response; + this.user = authResponse.getUsername() + "@" + this.host; + if (authResponse.getResource() != null) { + this.user += "/" + authResponse.getResource(); + } + } // We're done with the collector, so explicitly cancel it. collector.cancel(); @@ -322,6 +321,7 @@ public class XMPPConnection { // 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. @@ -334,9 +334,72 @@ public class XMPPConnection { } } + /** + * Logs in to the server anonymously. Very few servers are configured to support anonymous + * authentication, so it's fairly likely logging in anonymously will fail. If anonymous login + * does succeed, your XMPP address will likely be in the form "server/123ABC" (where "123ABC" is a + * random value generated by the server). + * + * @throws XMPPException if an error occurs or anonymous logins are not supported by the server. + * @throws IllegalStateException if not connected to the server, or already logged in + * to the serrver. + */ + public synchronized void loginAnonymously() throws XMPPException { + if (!isConnected()) { + throw new IllegalStateException("Not connected to server."); + } + if (authenticated) { + throw new IllegalStateException("Already logged in to server."); + } + + // Create the authentication packet we'll send to the server. + Authentication auth = new Authentication(); + + PacketCollector collector = packetReader.createPacketCollector( + new PacketIDFilter(auth.getPacketID())); + // Send the packet. + packetWriter.sendPacket(auth); + // Wait up to five seconds for a response from the server. + IQ response = (IQ)collector.nextResult(5000); + if (response == null) { + throw new XMPPException("Anonymous login failed."); + } + else if (response.getType() == IQ.Type.ERROR) { + throw new XMPPException(response.getError()); + } + // Set the user value. + if (response.getTo() != null) { + this.user = response.getTo(); + } + else { + this.user = this.host + "/" + ((Authentication)response).getResource(); + } + // We're done with the collector, so explicitly cancel it. + collector.cancel(); + + // Anonymous users can't have a roster. + roster = null; + + // Set presence to online. + packetWriter.sendPacket(new Presence(Presence.Type.AVAILABLE)); + + // Indicate that we're now authenticated. + authenticated = true; + anonymous = true; + + // If debugging is enabled, change the the debug window title to include the + // name we are now logged-in as. + if (DEBUG_ENABLED) { + String title = "Smack Debug Window -- " + getHost() + ":" + getPort(); + title += "/" + StringUtils.parseResource(user); + debugFrame.setTitle(title); + } + } + /** * Returns the roster for the user logged into the server. If the user has not yet - * logged into the server, this method will return null. + * logged into the server (or if the user is logged in anonymously), this method will return + * null. * * @return the user's roster, or null if the user has not logged in yet. */ @@ -421,6 +484,15 @@ public class XMPPConnection { return authenticated; } + /** + * Returns true if currently authenticated anonymously. + * + * @return true if authenticated anonymously. + */ + public boolean isAnonymous() { + return anonymous; + } + /** * Closes the connection by setting presence to unavailable then closing the stream to * the XMPP server. Once a connection has been closed, it cannot be re-opened.