diff --git a/source/org/jivesoftware/smack/AccountManager.java b/source/org/jivesoftware/smack/AccountManager.java index c538dddc1..0e9edaafb 100644 --- a/source/org/jivesoftware/smack/AccountManager.java +++ b/source/org/jivesoftware/smack/AccountManager.java @@ -1,3 +1,55 @@ +/** + * $RCSfile$ + * $Revision$ + * $Date$ + * + * Copyright (C) 2002-2003 Jive Software. All rights reserved. + * ==================================================================== + * The Jive Software License (based on Apache Software License, Version 1.1) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by + * Jive Software (http://www.jivesoftware.com)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Smack" and "Jive Software" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please + * contact webmaster@jivesoftware.com. + * + * 5. Products derived from this software may not be called "Smack", + * nor may "Smack" appear in their name, without prior written + * permission of Jive Software. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + */ + package org.jivesoftware.smack; import org.jivesoftware.smack.packet.Registration; @@ -9,7 +61,7 @@ import java.util.*; /** * Allows creation and management of accounts on an XMPP server. * - * @see XMPPConnection#getAccountManager(); + * @see XMPPConnection#getAccountManager() * @author Matt Tucker */ public class AccountManager { @@ -17,14 +69,19 @@ public class AccountManager { private XMPPConnection connection; private Registration info = null; + /** + * Creates a new AccountManager instance. + * + * @param connection a connection to a XMPP server. + */ public AccountManager(XMPPConnection connection) { this.connection = connection; } /** - * Returns true if the server supports creating new accounts. Many servers require that - * you not be currently authenticated when creating new accounts, so the safest - * behavior is to only create new accounts when + * Returns true if the server supports creating new accounts. Many servers require + * that you not be currently authenticated when creating new accounts, so the safest + * behavior is to only create new accounts before having logged in to a server. * * @return true if the server support creating new accounts. */ @@ -40,6 +97,30 @@ public class AccountManager { } } + /** + * Returns an Iterator for the (String) names of the required account attributes. + * All attributes must be set when creating new accounts. The standard + * attributes are as follows:

+ * + * Typically, servers require no attributes when creating new accounts, or just + * the user's email address. + * + * @return the required account attributes. + */ public Iterator getAccountAttributes() { try { if (info == null) { @@ -54,30 +135,52 @@ public class AccountManager { return Collections.EMPTY_LIST.iterator(); } + /** + * Creates a new account using the specified username and password. The server may + * require a number of extra account attributes such as an email address and phone + * number. In that case, Smack will attempt to automatically set all required + * attributes with blank values, which may or may not be accepted by the server. + * Therefore, it's recommended to check the required account attributes and to let + * the end-user populate them with real values instead. + * + * @param username the username. + * @param password the password. + * @throws XMPPException if an error occurs creating the account. + */ public void createAccount(String username, String password) throws XMPPException { - if (!supportsAccountCreation()) { - throw new XMPPException("Server does not support account creation."); + // Create a map for all the required attributes, but give them blank values. + Map attributes = new HashMap(); + for (Iterator i=getAccountAttributes(); i.hasNext(); ) { + String attributeName = (String)i.next(); + attributes.put(attributeName, ""); } + createAccount(username, password, attributes); } + /** + * Creates a new account using the specified username, password and account attributes. + * The attributes Map must contain only String name/value pairs and must also have values + * for all required attributes. + * + * @param username the username. + * @param password the password. + * @param attributes the account attributes. + * @throws XMPPException if an error occurs creating the account. + * @see #getAccountAttributes() + */ public void createAccount(String username, String password, Map attributes) throws XMPPException { - - } - - public void deleteAccount() throws XMPPException { - if (!connection.isAuthenticated()) { - throw new IllegalStateException("Must be logged in to delete a account."); + if (!supportsAccountCreation()) { + throw new XMPPException("Server does not support account creation."); } Registration reg = new Registration(); reg.setType(IQ.Type.SET); - Map attributes = new HashMap(); - // To delete an account, we add a single attribute, "remove", that is blank. - attributes.put("remove", ""); + reg.setUsername(username); + reg.setPassword(password); reg.setAttributes(attributes); PacketFilter filter = new AndFilter(new PacketIDFilter(reg.getPacketID()), - new PacketTypeFilter(Registration.class)); + new PacketTypeFilter(IQ.class)); PacketCollector collector = connection.createPacketCollector(filter); connection.sendPacket(reg); IQ result = (IQ)collector.nextResult(5000); @@ -89,6 +192,68 @@ public class AccountManager { } } + /** + * Changes the password of the currently logged-in account. This operation can only + * be performed after a successful login operation has been completed. Not all servers + * support changing passwords; an XMPPException will be thrown when that is the case. + * + * @throws IllegalStateException if not currently logged-in to the server. + * @throws XMPPException if an error occurs when changing the password. + */ + public void changePassword(String newPassword) throws XMPPException { + Registration reg = new Registration(); + reg.setType(IQ.Type.SET); + reg.setUsername(connection.getUsername()); + reg.setPassword(newPassword); + PacketFilter filter = new AndFilter(new PacketIDFilter(reg.getPacketID()), + new PacketTypeFilter(IQ.class)); + PacketCollector collector = connection.createPacketCollector(filter); + connection.sendPacket(reg); + IQ result = (IQ)collector.nextResult(5000); + if (result == null) { + throw new XMPPException("No response from server."); + } + else if (result.getType() == IQ.Type.ERROR) { + throw new XMPPException(result.getError()); + } + } + + /** + * Deletes the currently logged-in account from the server. This operation can only + * be performed after a successful login operation has been completed. Not all servers + * support deleting accounts; an XMPPException will be thrown when that is the case. + * + * @throws IllegalStateException if not currently logged-in to the server. + * @throws XMPPException if an error occurs when deleting the account. + */ + public void deleteAccount() throws XMPPException { + if (!connection.isAuthenticated()) { + throw new IllegalStateException("Must be logged in to delete a account."); + } + Registration reg = new Registration(); + reg.setType(IQ.Type.SET); + Map attributes = new HashMap(); + // To delete an account, we add a single attribute, "remove", that is blank. + attributes.put("remove", ""); + reg.setAttributes(attributes); + PacketFilter filter = new AndFilter(new PacketIDFilter(reg.getPacketID()), + new PacketTypeFilter(IQ.class)); + PacketCollector collector = connection.createPacketCollector(filter); + connection.sendPacket(reg); + IQ result = (IQ)collector.nextResult(5000); + if (result == null) { + throw new XMPPException("No response from server."); + } + else if (result.getType() == IQ.Type.ERROR) { + throw new XMPPException(result.getError()); + } + } + + /** + * Gets the account registration info from the server. + * + * @throws XMPPException if an error occurs. + */ private synchronized void getRegistrationInfo() throws XMPPException { Registration reg = new Registration(); PacketFilter filter = new AndFilter(new PacketIDFilter(reg.getPacketID()), diff --git a/source/org/jivesoftware/smack/XMPPConnection.java b/source/org/jivesoftware/smack/XMPPConnection.java index 00df24970..d657222cb 100644 --- a/source/org/jivesoftware/smack/XMPPConnection.java +++ b/source/org/jivesoftware/smack/XMPPConnection.java @@ -101,6 +101,8 @@ public class XMPPConnection { protected Socket socket; String connectionID; + private String username = null; + private String resource = null; private boolean connected = false; private boolean authenticated = false; @@ -183,6 +185,31 @@ public class XMPPConnection { return port; } + /** + * Returns the username that was used to login or null if not logged in yet. + * + * @return the username used to login. + */ + public String getUsername() { + 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; + } + /** * Logs in to the server using the strongest authentication mode supported by * the server, then set our presence to available. If more than five seconds @@ -219,6 +246,8 @@ 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(); @@ -302,8 +331,9 @@ public class XMPPConnection { } /** - * Returns an account manager instance for this - * @return + * Returns an account manager instance for this connection. + * + * @return an account manager for this connection. */ public synchronized AccountManager getAccountManager() { if (accountManager == null) {