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-argdelegation,bundle-zrtp4j,
bundle-filehistory,bundle-metahistory,bundle-metahistory-slick,
bundle-facebook,bundle-plugin-facebookaccregwizz,
bundle-plugin-facebookaccregwizz,
bundle-bouncycastle,bundle-plugin-otr,bundle-plugin-iptelaccregwizz"/>
<!--BUNDLE-SC-LAUNCHER-->
@ -1304,6 +1304,7 @@ javax.swing.event, javax.swing.border"/>
prefix="resources/images">
<include name="protocol/icq/**/*"/>
<include name="protocol/googletalk/**/*"/>
<include name="protocol/facebook/**/*"/>
<include name="protocol/jabber/**/*"/>
<include name="protocol/msn/**/*"/>
<include name="protocol/yahoo/**/*"/>
@ -1475,21 +1476,6 @@ javax.swing.event, javax.swing.border"/>
</jar>
</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 -->
<target name="bundle-ui-service">
<!-- Bundle sip-communicator's UI.-->

@ -31,5 +31,6 @@ Export-Package: org.jivesoftware.smack,
org.jivesoftware.smackx.jingle.listeners,
org.jivesoftware.smackx.filetransfer,
org.jivesoftware.smackx.provider,
org.jivesoftware.smack.sasl,
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
# 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.INVALID_EMAIL_ADDRESS=Invalid email address
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 username
plugin.facebookaccregwizz.PROTOCOL_DESCRIPTION=The Facebook Chat protocol
plugin.facebookaccregwizz.PROTOCOL_NAME=Facebook
plugin.facebookaccregwizz.USERNAME=Email:
plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Email and Password
plugin.facebookaccregwizz.USERNAME=Username:
plugin.facebookaccregwizz.USERNAME_AND_PASSWORD=Username and Password
# generalconfig
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.jabberconstants.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.impl.protocol.jabber.sasl.*;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.packet.*;
@ -375,6 +376,13 @@ private synchronized void connectAndLogin(SecurityAuthority authority,
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
{
connection.login(userID, password, accountResource);

@ -10,6 +10,7 @@ Import-Package: org.osgi.framework,
org.jivesoftware.smack.provider,
org.jivesoftware.smack.util,
org.jivesoftware.smack.filter,
org.jivesoftware.smack.sasl,
org.jivesoftware.smackx,
org.jivesoftware.smackx.muc,
org.jivesoftware.smackx.packet,
@ -34,4 +35,5 @@ Import-Package: org.osgi.framework,
org.xmlpull.v1,
org.xmlpull.mxp1,
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 = "("
+ ProtocolProviderFactory.PROTOCOL
+ "=" + "Facebook" + ")";
+ "=" + ProtocolNames.JABBER + ")";
try
{

@ -14,26 +14,26 @@
*/
public class FacebookAccountRegistration
{
private String email;
private String username;
private String password;
private boolean rememberPassword;
/**
* Returns the Email of the facebook registration account.
* @return the Email of the facebook registration account.
* Returns the username 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.
* @param email the userID of the facebook registration account.
* Sets the username 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;
public static final String SERVER_ADDRESS = "chat.facebook.com";
/**
* The object that we use to store details on an account that we will be
* creating.
@ -121,7 +123,7 @@ public Iterator<Map.Entry<String, String>> getSummary()
{
Map<String, String> summaryTable = new Hashtable<String, String>();
summaryTable.put("User ID", registration.getEmail());
summaryTable.put("User ID", registration.getUsername());
return summaryTable.entrySet().iterator();
}
@ -134,7 +136,7 @@ public ProtocolProviderService signin()
if (!firstWizardPage.isCommitted())
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>();
/* 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())
{
accountProperties.put( ProtocolProviderFactory.PASSWORD,
registration.getPassword());
}
accountProperties.put("SEND_KEEP_ALIVE", Boolean.TRUE.toString());
if (isModification)
{
providerFactory.uninstallAccount(protocolProvider.getAccountID());
@ -177,6 +188,15 @@ public ProtocolProviderService installAccount(
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;
try

@ -16,7 +16,7 @@
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.
*
* @author Dai Zhiwei
@ -29,7 +29,7 @@ public class FirstWizardPage
{
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
= new TransparentPanel(new BorderLayout(10, 10));
@ -38,7 +38,7 @@ public class FirstWizardPage
private JPanel valuesPanel = new TransparentPanel();
private JLabel emailLabel
private JLabel usernameLabel
= new JLabel(Resources.getString("plugin.facebookaccregwizz.USERNAME"));
private JLabel passLabel
@ -49,9 +49,9 @@ public class FirstWizardPage
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();
@ -93,32 +93,32 @@ public FirstWizardPage(FacebookAccountRegistrationWizard wizard)
*/
private void init()
{
this.emailField.getDocument().addDocumentListener(this);
this.usernameField.getDocument().addDocumentListener(this);
this.rememberPassBox.setSelected(true);
this.rememberPassBox.setOpaque(false);
this.existingAccountLabel.setForeground(Color.RED);
this.emailExampleLabel.setForeground(Color.GRAY);
this.emailExampleLabel.setFont(
emailExampleLabel.getFont().deriveFont(8));
this.usernameExampleLabel.setForeground(Color.GRAY);
this.usernameExampleLabel.setFont(
usernameExampleLabel.getFont().deriveFont(8));
this.emptyPanel.setMaximumSize(new Dimension(40, 35));
this.emailExampleLabel.setBorder(
this.usernameExampleLabel.setBorder(
BorderFactory.createEmptyBorder(0, 0, 8,0));
labelsPanel.add(emailLabel);
labelsPanel.add(usernameLabel);
labelsPanel.add(emptyPanel);
labelsPanel.add(passLabel);
valuesPanel.add(emailField);
valuesPanel.add(emailExampleLabel);
valuesPanel.add(usernameField);
valuesPanel.add(usernameExampleLabel);
valuesPanel.add(passField);
JLabel experimentalWarningLabel
= new JLabel(
Resources.getString(
"plugin.facebookaccregwizz.EXPERIMENTAL_WARNING"));
experimentalWarningLabel.setForeground(Color.RED);
"plugin.facebookaccregwizz.DESCRIPTION"));
experimentalWarningLabel.setHorizontalAlignment(JLabel.CENTER);
setPreferredWidthInCharCount(experimentalWarningLabel, 50);
userPassPanel.add(experimentalWarningLabel, BorderLayout.NORTH);
@ -212,7 +212,7 @@ public Object getWizardForm()
*/
public void pageShowing()
{
this.setNextButtonAccordingToEmail();
this.setNextButtonAccordingToUsername();
}
/**
@ -220,7 +220,12 @@ public void pageShowing()
*/
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))
{
@ -236,7 +241,7 @@ public void commitPage()
FacebookAccountRegistration registration
= wizard.getRegistration();
registration.setEmail(emailField.getText());
registration.setUsername(userID);
if (passField.getPassword() != null)
registration.setPassword(new String(passField.getPassword()));
@ -251,9 +256,9 @@ public void commitPage()
* Enables or disables the "Next" wizard button according to whether the
* 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);
}
@ -272,7 +277,7 @@ private void setNextButtonAccordingToEmail()
*/
public void insertUpdate(DocumentEvent event)
{
this.setNextButtonAccordingToEmail();
this.setNextButtonAccordingToUsername();
}
/**
@ -284,7 +289,7 @@ public void insertUpdate(DocumentEvent event)
*/
public void removeUpdate(DocumentEvent event)
{
this.setNextButtonAccordingToEmail();
this.setNextButtonAccordingToUsername();
}
public void changedUpdate(DocumentEvent event)
@ -315,8 +320,8 @@ public void loadAccount(ProtocolProviderService protocolProvider)
String password = accountID.getAccountProperties()
.get(ProtocolProviderFactory.PASSWORD);
this.emailField.setEnabled(false);
this.emailField.setText(accountID.getUserID());
this.usernameField.setEnabled(false);
this.usernameField.setText(accountID.getUserID());
if (password != null)
{
@ -329,11 +334,11 @@ public void loadAccount(ProtocolProviderService protocolProvider)
* Verifies whether there is already an account installed with the same
* 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
* otherwise.
*/
private boolean isExistingAccount(String email)
private boolean isExistingAccount(String username)
{
ProtocolProviderFactory factory
= FacebookAccRegWizzActivator.getFacebookProtocolProviderFactory();
@ -341,16 +346,24 @@ private boolean isExistingAccount(String email)
Iterable<AccountID> registeredAccounts = factory.getRegisteredAccounts();
for (AccountID accountID : registeredAccounts)
if (email.equalsIgnoreCase(accountID.getUserID()))
if (username.equalsIgnoreCase(accountID.getUserID()))
return true;
return false;
}
/**
* The simple form.
* @return
*/
public Object getSimpleForm()
{
return userPassPanel;
}
/**
* Is committed.
* @return Is committed.
*/
public boolean isCommitted()
{
return isCommitted;

Loading…
Cancel
Save