Make the OTR <authenticate buddy> text clickable (Patch by Daniel Perren, FHNW)

cusax-fix
Ingo Bauersachs 14 years ago
parent 63c9ed630a
commit 05f4510756

@ -1292,7 +1292,7 @@ plugin.otr.configform.COLUMN_NAME_CONTACT=Contact
plugin.otr.configform.COLUMN_NAME_VERIFIED_STATUS=Verified
plugin.otr.configform.COLUMN_VALUE_VERIFIED_TRUE=Yes
plugin.otr.configform.COLUMN_VALUE_VERIFIED_FALSE=No
plugin.otr.activator.unverifiedsessionwarning={0} is contacting you from an unrecognized computer. <u>You should authenticate this buddy</u>.
plugin.otr.activator.unverifiedsessionwarning={0} is contacting you from an unrecognized computer. You should <A href=\"jitsi://{1}/{2}?{3}\">authenticate {0}</a>.
plugin.otr.activator.unverifiedsessionstared=<b>Unverified</b> private conversation with {0} started.
plugin.otr.activator.sessionstared=Private conversation with {0} started.
plugin.otr.activator.sessionfinished={0} has ended his/her private conversation with you; you should do the same.

@ -10,6 +10,7 @@
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.Map.*;
import java.util.regex.*;
@ -76,9 +77,17 @@ public class ChatConversationPanel
"("
+ "(\\bwww\\.[^\\s<>\"]+\\.[^\\s<>\"]+/*[?#]*(\\w+[&=;?]\\w+)*\\b)" // wwwURL
+ "|"
+ "(\\bjitsi\\:[^\\s<>\"]+\\.[^\\s<>\"]*\\b)" // internalURL
+ "|"
+ "(\\b\\w+://[^\\s<>\"]+/*[?#]*(\\w+[&=;?]\\w+)*\\b)" // protocolURL
+ ")");
/**
* List for observing text messages.
*/
private Set<ChatLinkClickedListener> chatLinkClickedListeners =
new HashSet<ChatLinkClickedListener>();
/**
* The component rendering chat conversation panel text.
*/
@ -1072,6 +1081,8 @@ public long getLastIncomingMsgTimestamp()
/**
* When a right button click is performed in the editor pane, a popup menu
* is opened.
* In case of the Scheme being internal, it won't open the Browser but
* instead it will trigger the forwarded action.
*
* @param e The MouseEvent.
*/
@ -1088,7 +1099,25 @@ public void mouseClicked(MouseEvent e)
else if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0
&& currentHref != null && currentHref.length() != 0)
{
GuiActivator.getBrowserLauncher().openURL(currentHref);
URI uri;
try
{
uri = new URI(currentHref);
}
catch (URISyntaxException e1)
{
logger.error("Invalid URL", e1);
return;
}
if(uri.getScheme().equals("jitsi"))
{
for(ChatLinkClickedListener l:chatLinkClickedListeners)
{
l.chatLinkClicked(uri);
}
}
else
GuiActivator.getBrowserLauncher().openURL(currentHref);
// after opening the link remove the currentHref to avoid
// clicking on the window to gain focus to open the link again
@ -1104,7 +1133,8 @@ else if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0
*/
private void openContextMenu(Point p)
{
if (currentHref != null && currentHref.length() != 0)
if (currentHref != null && currentHref.length() != 0
&& !currentHref.startsWith("jitsi://"))
{
rightButtonMenu.insert(openLinkItem, 0);
rightButtonMenu.insert(copyLinkItem, 1);
@ -1431,6 +1461,28 @@ public void addComponent(ChatConversationComponent component)
}
}
/**
* Registers a new link click listener.
*
* @param listener the object that should be notified when an internal
* link was clicked.
*/
public void addChatLinkClickedListener(ChatLinkClickedListener listener)
{
if(!chatLinkClickedListeners.contains(listener))
chatLinkClickedListeners.add(listener);
}
/**
* Remove a registered link click listener.
*
* @param listener a registered click listener to remove
*/
public void removeChatLinkClickedListener(ChatLinkClickedListener listener)
{
chatLinkClickedListeners.remove(listener);
}
/**
* Returns the date string to show for the given date.
*

@ -2604,4 +2604,24 @@ public void chatRoomPropertyChanged(ChatRoomMemberPropertyChangeEvent event)
ChatConversationPanel.HTML_CONTENT_TYPE);
}
/**
* Add a new ChatLinkClickedListener
*
* @param listener ChatLinkClickedListener
*/
public void addChatLinkClickedListener(ChatLinkClickedListener listener)
{
conversationPanel.addChatLinkClickedListener(listener);
}
/**
* Remove existing ChatLinkClickedListener
*
* @param listener ChatLinkClickedListener
*/
public void removeChatLinkClickedListener(ChatLinkClickedListener listener)
{
conversationPanel.removeChatLinkClickedListener(listener);
}
}

@ -0,0 +1,36 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.plugin.otr;
import java.awt.*;
import net.java.sip.communicator.service.protocol.*;
/**
* Class for storing OTR functions used by the menus, buttons, links, etc.
*
* @author Daniel Perren
*/
class OtrActionHandlers
{
/**
* Opening the standard authorisation dialog for OTR fingerprints.
*
* @param contact the contact you would like to authenticate.
*/
static void openAuthDialog(Contact contact)
{
// Launch auth buddy dialog.
OtrBuddyAuthenticationDialog authenticateBuddyDialog =
new OtrBuddyAuthenticationDialog(contact);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
authenticateBuddyDialog.setLocation(screenSize.width / 2
- authenticateBuddyDialog.getWidth() / 2, screenSize.height / 2
- authenticateBuddyDialog.getHeight() / 2);
authenticateBuddyDialog.setVisible(true);
}
}

@ -120,17 +120,8 @@ else if (ACTION_COMMAND_REFRESH_OTR.equals(actionCommand))
OtrActivator.scOtrEngine.refreshSession(contact);
else if (ACTION_COMMAND_AUTHENTICATE_BUDDY.equals(actionCommand))
{
// Launch auth buddy dialog.
OtrBuddyAuthenticationDialog authenticateBuddyDialog =
new OtrBuddyAuthenticationDialog(contact);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
authenticateBuddyDialog.setLocation(screenSize.width / 2
- authenticateBuddyDialog.getWidth() / 2, screenSize.height / 2
- authenticateBuddyDialog.getHeight() / 2);
authenticateBuddyDialog.setVisible(true);
}
OtrActionHandlers.openAuthDialog(contact);
else if (ACTION_COMMAND_CB_ENABLE.equals(actionCommand))
{

@ -5,6 +5,7 @@
*/
package net.java.sip.communicator.plugin.otr;
import java.net.*;
import java.security.*;
import java.util.*;
@ -20,12 +21,13 @@
* @author George Politis
*/
public class ScOtrEngineImpl
implements ScOtrEngine
implements ScOtrEngine,
ChatLinkClickedListener
{
private final OtrConfigurator configurator = new OtrConfigurator();
private static final Map<SessionID, Contact> contactsMap =
new Hashtable<SessionID, Contact>();
private static final Map<ScSessionID, Contact> contactsMap =
new Hashtable<ScSessionID, Contact>();
private final List<String> injectedMessageUIDs = new Vector<String>();
@ -146,13 +148,30 @@ public void sessionStatusChanged(SessionID sessionID)
if (!OtrActivator.scOtrKeyManager.isVerified(contact))
{
UUID sessionGuid = null;
for(ScSessionID scSessionID : contactsMap.keySet())
{
if(scSessionID.getSessionID().equals(sessionID))
{
sessionGuid = scSessionID.getGUID();
break;
}
}
OtrActivator.uiService.getChat(contact)
.addChatLinkClickedListener(ScOtrEngineImpl.this);
String unverifiedSessionWarning =
OtrActivator.resourceService
.getI18NString(
"plugin.otr.activator.unverifiedsessionwarning",
new String[]
{ contact.getDisplayName() });
{
contact.getDisplayName(),
this.getClass().getName(),
"AUTHENTIFICATION",
sessionGuid.toString()
});
OtrActivator.uiService.getChat(contact).addMessage(
contact.getDisplayName(),
System.currentTimeMillis(), Chat.SYSTEM_MESSAGE,
@ -205,9 +224,13 @@ public static SessionID getSessionID(Contact contact)
.getAccountUniqueID(), contact.getAddress(), contact
.getProtocolProvider().getProtocolName());
if(contactsMap.containsKey(sessionID))
return sessionID;
ScSessionID scSessionID = new ScSessionID(sessionID);
synchronized (contactsMap)
{
contactsMap.put(sessionID, contact);
contactsMap.put(scSessionID, contact);
}
return sessionID;
@ -345,4 +368,22 @@ public void setContactPolicy(Contact contact, OtrPolicy policy)
for (ScOtrEngineListener l : listeners)
l.contactPolicyChanged(contact);
}
public void chatLinkClicked(URI url)
{
String action = url.getPath();
if(action.equals("/AUTHENTIFICATION"))
{
UUID guid = UUID.fromString(url.getQuery());
for(ScSessionID scSessionID : contactsMap.keySet())
{
if(scSessionID.getGUID().equals(guid))
{
Contact c = contactsMap.get(scSessionID.getSessionID());
OtrActionHandlers.openAuthDialog(c);
break;
}
}
}
}
}

@ -0,0 +1,84 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.plugin.otr;
import java.util.*;
import net.java.otr4j.session.*;
/**
* Class used to associate a random UUID to an OTR4J SessionID.
*
* @author Daniel Perren
*/
public class ScSessionID
{
private SessionID sessionID;
private UUID guid = UUID.randomUUID();
/**
* Creates a new instance of this class.
* @param sessionID the OTR4J SessionID that is being wrapped.
*/
public ScSessionID(SessionID sessionID)
{
this.sessionID = sessionID;
}
/**
* Gets the wrapped session ID
*
* @return sessionID
*/
public SessionID getSessionID()
{
return sessionID;
}
/**
* Returns {@link SessionID#hashCode()} of the wrapped SessionID.
* @return HashCode of the wrapped SessionID.
*/
@Override
public int hashCode()
{
return sessionID.hashCode();
}
/**
* Get the current GUID.
*
* @return The GUID generated for this SessionID.
*/
public UUID getGUID()
{
return guid;
}
/**
* Overrides equals() for the ability to get the hashcode from sessionID.
* @param obj the object to compare
* @return true if the objects are considered equal.
*/
@Override
public boolean equals(Object obj)
{
if(obj == null)
return false;
return sessionID.toString().equals(obj.toString());
}
/**
* Returns {@link SessionID#toString()} of the wrapped SessionID.
* @return String representation of the wrapped SessionID.
*/
@Override
public String toString()
{
return sessionID.toString();
}
}

@ -197,6 +197,27 @@ public interface Chat
public void addMessage(String contactName, long date, String messageType,
String message, String contentType);
/**
* Adds a new ChatLinkClickedListener. The callback is called for every
* link whose scheme is <tt>jitsi</tt>. It is the callback's responsibility
* to filter the action based on the URI.
*
* Example:<br>
* <tt>jitsi://classname/action?query</tt><br>
* Use the name of the registering class as the host, the action to execute
* as the path and any parameters as the query.
*
* @param listener callback that is notified when a link was clicked.
*/
public void addChatLinkClickedListener(ChatLinkClickedListener listener);
/**
* Removes an existing ChatLinkClickedListener
*
* @param listener the already registered listener to remove.
*/
public void removeChatLinkClickedListener(ChatLinkClickedListener listener);
/**
* Provides the {@link Highlighter} used in rendering the chat editor.
*

@ -0,0 +1,24 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.service.gui;
import java.net.*;
/**
* Event-callback for clicks on links.
*
* @author Daniel Perren
*/
public interface ChatLinkClickedListener
{
/**
* Callback that is executed when a link was clicked.
*
* @param url The URI of the link that was clicked.
*/
public void chatLinkClicked(URI url);
}
Loading…
Cancel
Save