Introduce new support for Facebook, through xmpp. Remove old one.

cusax-fix
Damian Minkov 16 years ago
parent 19ad20f4a1
commit d7092d65dd

@ -885,7 +885,7 @@
bundle-plugin-googletalkaccregwizz,bundle-argdelegation-service, bundle-plugin-googletalkaccregwizz,bundle-argdelegation-service,
bundle-argdelegation,bundle-zrtp4j, bundle-argdelegation,bundle-zrtp4j,
bundle-filehistory,bundle-metahistory,bundle-metahistory-slick, bundle-filehistory,bundle-metahistory,bundle-metahistory-slick,
bundle-facebook,bundle-plugin-facebookaccregwizz, bundle-plugin-facebookaccregwizz,
bundle-bouncycastle,bundle-plugin-otr,bundle-plugin-iptelaccregwizz"/> bundle-bouncycastle,bundle-plugin-otr,bundle-plugin-iptelaccregwizz"/>
<!--BUNDLE-SC-LAUNCHER--> <!--BUNDLE-SC-LAUNCHER-->
@ -1304,6 +1304,7 @@ javax.swing.event, javax.swing.border"/>
prefix="resources/images"> prefix="resources/images">
<include name="protocol/icq/**/*"/> <include name="protocol/icq/**/*"/>
<include name="protocol/googletalk/**/*"/> <include name="protocol/googletalk/**/*"/>
<include name="protocol/facebook/**/*"/>
<include name="protocol/jabber/**/*"/> <include name="protocol/jabber/**/*"/>
<include name="protocol/msn/**/*"/> <include name="protocol/msn/**/*"/>
<include name="protocol/yahoo/**/*"/> <include name="protocol/yahoo/**/*"/>
@ -1475,21 +1476,6 @@ javax.swing.event, javax.swing.border"/>
</jar> </jar>
</target> </target>
<!-- BUNDLE-FACEBOOK -->
<target name="bundle-facebook">
<!-- Creates a bundle containing the Facebook impl of the protocol provider.-->
<jar compress="false" destfile="${bundles.dest}/protocol-facebook.jar"
manifest="${src}/net/java/sip/communicator/impl/protocol/facebook/facebook.provider.manifest.mf">
<zipfileset dir="${dest}/net/java/sip/communicator/impl/protocol/facebook"
prefix="net/java/sip/communicator/impl/protocol/facebook"/>
<zipfileset dir="${resources}/images/protocol/facebook"
prefix="resources/images/protocol/facebook" />
<zipfileset src="${lib.noinst}/commons-codec-1.3.jar" prefix=""/>
<zipfileset src="${lib.noinst}/httpclient-4.0-beta2.jar" prefix=""/>
<zipfileset src="${lib.noinst}/json-20090723.jar" prefix=""/>
</jar>
</target>
<!-- BUNDLE-UI-SERVICE --> <!-- BUNDLE-UI-SERVICE -->
<target name="bundle-ui-service"> <target name="bundle-ui-service">
<!-- Bundle sip-communicator's UI.--> <!-- Bundle sip-communicator's UI.-->

@ -31,5 +31,6 @@ Export-Package: org.jivesoftware.smack,
org.jivesoftware.smackx.jingle.listeners, org.jivesoftware.smackx.jingle.listeners,
org.jivesoftware.smackx.filetransfer, org.jivesoftware.smackx.filetransfer,
org.jivesoftware.smackx.provider, org.jivesoftware.smackx.provider,
org.jivesoftware.smack.sasl,
org.xmlpull.v1, org.xmlpull.v1,
org.xmlpull.mxp1 org.xmlpull.mxp1

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 B

@ -537,12 +537,12 @@ plugin.callhistoryform.INCOMING=Incoming
plugin.callhistoryform.OUTGOING=Outgoing plugin.callhistoryform.OUTGOING=Outgoing
# facebookaccregwizz # facebookaccregwizz
plugin.facebookaccregwizz.EXPERIMENTAL_WARNING=<html><body>The support for this protocol is experimental and may not work as expected. Please report bugs to <a href="mailto:dev@sip-communicator.dev.java.net">dev@sip-communicator.dev.java.net</a>.</body></html> plugin.facebookaccregwizz.DESCRIPTION=<html><body><center>User must have registered its username through Facebook profile settings page.</center></body></html>
plugin.facebookaccregwizz.INVALID_EMAIL_ADDRESS=Invalid email address plugin.facebookaccregwizz.INVALID_EMAIL_ADDRESS=Invalid username
plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=The Facebook Chat protocol plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=The Facebook Chat protocol
plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
plugin.facebookaccregwizz.USERNAME=Email: plugin.facebookaccregwizz.USERNAME=Username:
plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Email and Password plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Username and Password
# generalconfig # generalconfig
plugin.generalconfig.AUTO_START=Auto - start {0} when computer restarts or reboots. plugin.generalconfig.AUTO_START=Auto - start {0} when computer restarts or reboots.

@ -14,6 +14,7 @@
import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.service.protocol.jabberconstants.*; import net.java.sip.communicator.service.protocol.jabberconstants.*;
import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.*;
import net.java.sip.communicator.impl.protocol.jabber.sasl.*;
import org.jivesoftware.smack.*; import org.jivesoftware.smack.*;
import org.jivesoftware.smack.packet.*; import org.jivesoftware.smack.packet.*;
@ -375,6 +376,13 @@ private synchronized void connectAndLogin(SecurityAuthority authority,
SASLAuthentication.supportSASLMechanism("PLAIN", 0); SASLAuthentication.supportSASLMechanism("PLAIN", 0);
// Insert our sasl mechanism implementation
// in order to support some incompatable servers
SASLAuthentication.unregisterSASLMechanism("DIGEST-MD5");
SASLAuthentication.registerSASLMechanism("DIGEST-MD5",
SASLDigestMD5Mechanism.class);
SASLAuthentication.supportSASLMechanism("DIGEST-MD5");
try try
{ {
connection.login(userID, password, accountResource); connection.login(userID, password, accountResource);

@ -10,6 +10,7 @@ Import-Package: org.osgi.framework,
org.jivesoftware.smack.provider, org.jivesoftware.smack.provider,
org.jivesoftware.smack.util, org.jivesoftware.smack.util,
org.jivesoftware.smack.filter, org.jivesoftware.smack.filter,
org.jivesoftware.smack.sasl,
org.jivesoftware.smackx, org.jivesoftware.smackx,
org.jivesoftware.smackx.muc, org.jivesoftware.smackx.muc,
org.jivesoftware.smackx.packet, org.jivesoftware.smackx.packet,
@ -34,4 +35,5 @@ Import-Package: org.osgi.framework,
org.xmlpull.v1, org.xmlpull.v1,
org.xmlpull.mxp1, org.xmlpull.mxp1,
javax.xml.parsers, javax.xml.parsers,
org.w3c.dom javax.security.sasl,
javax.security.auth.callback

@ -0,0 +1,116 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.protocol.jabber.sasl;
import java.io.*;
import java.util.*;
import javax.security.auth.callback.*;
import javax.security.sasl.*;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.util.Base64;
/**
* Creates our custom SASLDigestMD5Mechanism with some changes in order
* to be compatible with some jabber servers.
* @author Damian Minkov
*/
public class SASLDigestMD5Mechanism
extends org.jivesoftware.smack.sasl.SASLDigestMD5Mechanism
{
/**
* Creates our mechanism.
* @param saslAuthentication
*/
public SASLDigestMD5Mechanism(SASLAuthentication saslAuthentication)
{
super(saslAuthentication);
}
/**
* Builds and sends the <tt>auth</tt> stanza to the server. Note that this method of
* authentication is not recommended, since it is very inflexible. Use
* {@link #authenticate(String, String, CallbackHandler)} whenever possible.
*
* @param username the username of the user being authenticated.
* @param host the hostname where the user account resides.
* @param password the password for this account.
* @throws IOException If a network error occurs while authenticating.
* @throws XMPPException If a protocol error occurs or the user is not authenticated.
*/
public void authenticate(String username, String host, String password)
throws IOException, XMPPException
{
//Since we were not provided with a CallbackHandler, we will use our own with the given
//information
//Set the authenticationID as the username, since they must be the same in this case.
this.authenticationId = username;
this.password = password;
this.hostname = host;
String[] mechanisms = { getName() };
Map<String,String> props = new HashMap<String,String>();
sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, this);
authenticate();
}
/**
* Builds and sends the <tt>auth</tt> stanza to the server. The callback handler will handle
* any additional information, such as the authentication ID or realm, if it is needed.
*
* @param username the username of the user being authenticated.
* @param host the hostname where the user account resides.
* @param cbh the CallbackHandler to obtain user information.
* @throws IOException If a network error occurs while authenticating.
* @throws XMPPException If a protocol error occurs or the user is not authenticated.
*/
public void authenticate(String username, String host, CallbackHandler cbh)
throws IOException, XMPPException
{
String[] mechanisms = { getName() };
Map<String,String> props = new HashMap<String,String>();
sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, cbh);
authenticate();
}
/**
* The server is challenging the SASL mechanism for the stanza he just sent. Send a
* response to the server's challenge.
*
* @param challenge a base64 encoded string representing the challenge.
* @throws IOException if an exception sending the response occurs.
*/
public void challengeReceived(String challenge)
throws IOException
{
// Build the challenge response stanza encoding the response text
StringBuilder stanza = new StringBuilder();
byte response[];
if(challenge != null) {
response = sc.evaluateChallenge(Base64.decode(challenge));
} else {
response = sc.evaluateChallenge(null);
}
String authenticationText = null;
if(null != response) {
authenticationText = Base64.encodeBytes(response,Base64.DONT_BREAK_LINES);
}
if((null == authenticationText) || (authenticationText.equals(""))) {
authenticationText = "=";
}
stanza.append("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
stanza.append(authenticationText);
stanza.append("</response>");
// Send the authentication to the server
getSASLAuthentication().send(stanza.toString());
}
}

@ -92,7 +92,7 @@ public static ProtocolProviderFactory getFacebookProtocolProviderFactory()
String osgiFilter = "(" String osgiFilter = "("
+ ProtocolProviderFactory.PROTOCOL + ProtocolProviderFactory.PROTOCOL
+ "=" + "Facebook" + ")"; + "=" + ProtocolNames.JABBER + ")";
try try
{ {

@ -14,26 +14,26 @@
*/ */
public class FacebookAccountRegistration public class FacebookAccountRegistration
{ {
private String email; private String username;
private String password; private String password;
private boolean rememberPassword; private boolean rememberPassword;
/** /**
* Returns the Email of the facebook registration account. * Returns the username of the facebook registration account.
* @return the Email of the facebook registration account. * @return the username of the facebook registration account.
*/ */
public String getEmail() public String getUsername()
{ {
return email; return username;
} }
/** /**
* Sets the Email of the facebook registration account. * Sets the username of the facebook registration account.
* @param email the userID of the facebook registration account. * @param username the userID of the facebook registration account.
*/ */
public void setEmail(String email) public void setUsername(String username)
{ {
this.email = email; this.username = username;
} }
/** /**

@ -30,6 +30,8 @@ public class FacebookAccountRegistrationWizard
*/ */
private FirstWizardPage firstWizardPage; private FirstWizardPage firstWizardPage;
public static final String SERVER_ADDRESS = "chat.facebook.com";
/** /**
* The object that we use to store details on an account that we will be * The object that we use to store details on an account that we will be
* creating. * creating.
@ -121,7 +123,7 @@ public Iterator<Map.Entry<String, String>> getSummary()
{ {
Map<String, String> summaryTable = new Hashtable<String, String>(); Map<String, String> summaryTable = new Hashtable<String, String>();
summaryTable.put("User ID", registration.getEmail()); summaryTable.put("User ID", registration.getUsername());
return summaryTable.entrySet().iterator(); return summaryTable.entrySet().iterator();
} }
@ -134,7 +136,7 @@ public ProtocolProviderService signin()
if (!firstWizardPage.isCommitted()) if (!firstWizardPage.isCommitted())
firstWizardPage.commitPage(); firstWizardPage.commitPage();
return signin(registration.getEmail(), null); return signin(registration.getUsername(), null);
} }
/** /**
@ -164,12 +166,21 @@ public ProtocolProviderService installAccount(
{ {
Map<String, String> accountProperties = new Hashtable<String, String>(); Map<String, String> accountProperties = new Hashtable<String, String>();
/* Make the account use the resources specific to Facebook. */
accountProperties.put(ProtocolProviderFactory.PROTOCOL,
ProtocolNames.FACEBOOK);
accountProperties
.put(ProtocolProviderFactory.PROTOCOL_ICON_PATH,
"resources/images/protocol/facebook");
if (registration.isRememberPassword()) if (registration.isRememberPassword())
{ {
accountProperties.put( ProtocolProviderFactory.PASSWORD, accountProperties.put( ProtocolProviderFactory.PASSWORD,
registration.getPassword()); registration.getPassword());
} }
accountProperties.put("SEND_KEEP_ALIVE", Boolean.TRUE.toString());
if (isModification) if (isModification)
{ {
providerFactory.uninstallAccount(protocolProvider.getAccountID()); providerFactory.uninstallAccount(protocolProvider.getAccountID());
@ -177,6 +188,15 @@ public ProtocolProviderService installAccount(
this.isModification = false; this.isModification = false;
} }
accountProperties.put(ProtocolProviderFactory.SERVER_ADDRESS,
SERVER_ADDRESS);
accountProperties.put(ProtocolProviderFactory.SERVER_PORT, "5222");
accountProperties.put(ProtocolProviderFactory.RESOURCE, "sip-comm");
accountProperties.put(ProtocolProviderFactory.RESOURCE_PRIORITY, "10");
Throwable exception = null; Throwable exception = null;
try try

@ -16,7 +16,7 @@
import net.java.sip.communicator.util.swing.*; import net.java.sip.communicator.util.swing.*;
/** /**
* The <tt>FirstWizardPage</tt> is the page, where user could enter the email * The <tt>FirstWizardPage</tt> is the page, where user could enter the username
* and the password of the account. * and the password of the account.
* *
* @author Dai Zhiwei * @author Dai Zhiwei
@ -29,7 +29,7 @@ public class FirstWizardPage
{ {
public static final String FIRST_PAGE_IDENTIFIER = "FirstPageIdentifier"; public static final String FIRST_PAGE_IDENTIFIER = "FirstPageIdentifier";
public static final String USER_NAME_EXAMPLE = "Ex: username@email.com"; public static final String USER_NAME_EXAMPLE = "Ex: username";
private JPanel userPassPanel private JPanel userPassPanel
= new TransparentPanel(new BorderLayout(10, 10)); = new TransparentPanel(new BorderLayout(10, 10));
@ -38,7 +38,7 @@ public class FirstWizardPage
private JPanel valuesPanel = new TransparentPanel(); private JPanel valuesPanel = new TransparentPanel();
private JLabel emailLabel private JLabel usernameLabel
= new JLabel(Resources.getString("plugin.facebookaccregwizz.USERNAME")); = new JLabel(Resources.getString("plugin.facebookaccregwizz.USERNAME"));
private JLabel passLabel private JLabel passLabel
@ -49,9 +49,9 @@ public class FirstWizardPage
private JPanel emptyPanel = new TransparentPanel(); private JPanel emptyPanel = new TransparentPanel();
private JLabel emailExampleLabel = new JLabel(USER_NAME_EXAMPLE); private JLabel usernameExampleLabel = new JLabel(USER_NAME_EXAMPLE);
private JTextField emailField = new JTextField(); private JTextField usernameField = new JTextField();
private JPasswordField passField = new JPasswordField(); private JPasswordField passField = new JPasswordField();
@ -93,32 +93,32 @@ public FirstWizardPage(FacebookAccountRegistrationWizard wizard)
*/ */
private void init() private void init()
{ {
this.emailField.getDocument().addDocumentListener(this); this.usernameField.getDocument().addDocumentListener(this);
this.rememberPassBox.setSelected(true); this.rememberPassBox.setSelected(true);
this.rememberPassBox.setOpaque(false); this.rememberPassBox.setOpaque(false);
this.existingAccountLabel.setForeground(Color.RED); this.existingAccountLabel.setForeground(Color.RED);
this.emailExampleLabel.setForeground(Color.GRAY); this.usernameExampleLabel.setForeground(Color.GRAY);
this.emailExampleLabel.setFont( this.usernameExampleLabel.setFont(
emailExampleLabel.getFont().deriveFont(8)); usernameExampleLabel.getFont().deriveFont(8));
this.emptyPanel.setMaximumSize(new Dimension(40, 35)); this.emptyPanel.setMaximumSize(new Dimension(40, 35));
this.emailExampleLabel.setBorder( this.usernameExampleLabel.setBorder(
BorderFactory.createEmptyBorder(0, 0, 8,0)); BorderFactory.createEmptyBorder(0, 0, 8,0));
labelsPanel.add(emailLabel); labelsPanel.add(usernameLabel);
labelsPanel.add(emptyPanel); labelsPanel.add(emptyPanel);
labelsPanel.add(passLabel); labelsPanel.add(passLabel);
valuesPanel.add(emailField); valuesPanel.add(usernameField);
valuesPanel.add(emailExampleLabel); valuesPanel.add(usernameExampleLabel);
valuesPanel.add(passField); valuesPanel.add(passField);
JLabel experimentalWarningLabel JLabel experimentalWarningLabel
= new JLabel( = new JLabel(
Resources.getString( Resources.getString(
"plugin.facebookaccregwizz.EXPERIMENTAL_WARNING")); "plugin.facebookaccregwizz.DESCRIPTION"));
experimentalWarningLabel.setForeground(Color.RED); experimentalWarningLabel.setHorizontalAlignment(JLabel.CENTER);
setPreferredWidthInCharCount(experimentalWarningLabel, 50); setPreferredWidthInCharCount(experimentalWarningLabel, 50);
userPassPanel.add(experimentalWarningLabel, BorderLayout.NORTH); userPassPanel.add(experimentalWarningLabel, BorderLayout.NORTH);
@ -212,7 +212,7 @@ public Object getWizardForm()
*/ */
public void pageShowing() public void pageShowing()
{ {
this.setNextButtonAccordingToEmail(); this.setNextButtonAccordingToUsername();
} }
/** /**
@ -220,7 +220,12 @@ public void pageShowing()
*/ */
public void commitPage() public void commitPage()
{ {
String userID = emailField.getText().trim();
String userID = usernameField.getText().trim();
// add server part to username
if(userID.indexOf("@") == -1)
userID += "@" + FacebookAccountRegistrationWizard.SERVER_ADDRESS;
if (!wizard.isModification() && isExistingAccount(userID)) if (!wizard.isModification() && isExistingAccount(userID))
{ {
@ -236,7 +241,7 @@ public void commitPage()
FacebookAccountRegistration registration FacebookAccountRegistration registration
= wizard.getRegistration(); = wizard.getRegistration();
registration.setEmail(emailField.getText()); registration.setUsername(userID);
if (passField.getPassword() != null) if (passField.getPassword() != null)
registration.setPassword(new String(passField.getPassword())); registration.setPassword(new String(passField.getPassword()));
@ -251,9 +256,9 @@ public void commitPage()
* Enables or disables the "Next" wizard button according to whether the * Enables or disables the "Next" wizard button according to whether the
* User ID field is empty. * User ID field is empty.
*/ */
private void setNextButtonAccordingToEmail() private void setNextButtonAccordingToUsername()
{ {
if (emailField.getText() == null || emailField.getText().equals("")) if (usernameField.getText() == null || usernameField.getText().equals(""))
{ {
wizard.getWizardContainer().setNextFinishButtonEnabled(false); wizard.getWizardContainer().setNextFinishButtonEnabled(false);
} }
@ -272,7 +277,7 @@ private void setNextButtonAccordingToEmail()
*/ */
public void insertUpdate(DocumentEvent event) public void insertUpdate(DocumentEvent event)
{ {
this.setNextButtonAccordingToEmail(); this.setNextButtonAccordingToUsername();
} }
/** /**
@ -284,7 +289,7 @@ public void insertUpdate(DocumentEvent event)
*/ */
public void removeUpdate(DocumentEvent event) public void removeUpdate(DocumentEvent event)
{ {
this.setNextButtonAccordingToEmail(); this.setNextButtonAccordingToUsername();
} }
public void changedUpdate(DocumentEvent event) public void changedUpdate(DocumentEvent event)
@ -315,8 +320,8 @@ public void loadAccount(ProtocolProviderService protocolProvider)
String password = accountID.getAccountProperties() String password = accountID.getAccountProperties()
.get(ProtocolProviderFactory.PASSWORD); .get(ProtocolProviderFactory.PASSWORD);
this.emailField.setEnabled(false); this.usernameField.setEnabled(false);
this.emailField.setText(accountID.getUserID()); this.usernameField.setText(accountID.getUserID());
if (password != null) if (password != null)
{ {
@ -329,11 +334,11 @@ public void loadAccount(ProtocolProviderService protocolProvider)
* Verifies whether there is already an account installed with the same * Verifies whether there is already an account installed with the same
* details as the one that the user has just entered. * details as the one that the user has just entered.
* *
* @param email the name of the user that the account is registered for * @param username the name of the user that the account is registered for
* @return true if there is already an account for this userID and false * @return true if there is already an account for this userID and false
* otherwise. * otherwise.
*/ */
private boolean isExistingAccount(String email) private boolean isExistingAccount(String username)
{ {
ProtocolProviderFactory factory ProtocolProviderFactory factory
= FacebookAccRegWizzActivator.getFacebookProtocolProviderFactory(); = FacebookAccRegWizzActivator.getFacebookProtocolProviderFactory();
@ -341,16 +346,24 @@ private boolean isExistingAccount(String email)
Iterable<AccountID> registeredAccounts = factory.getRegisteredAccounts(); Iterable<AccountID> registeredAccounts = factory.getRegisteredAccounts();
for (AccountID accountID : registeredAccounts) for (AccountID accountID : registeredAccounts)
if (email.equalsIgnoreCase(accountID.getUserID())) if (username.equalsIgnoreCase(accountID.getUserID()))
return true; return true;
return false; return false;
} }
/**
* The simple form.
* @return
*/
public Object getSimpleForm() public Object getSimpleForm()
{ {
return userPassPanel; return userPassPanel;
} }
/**
* Is committed.
* @return Is committed.
*/
public boolean isCommitted() public boolean isCommitted()
{ {
return isCommitted; return isCommitted;

Loading…
Cancel
Save