Commit b4497851 authored by Daniel Henninger's avatar Daniel Henninger Committed by dhenninger

Added support for MUC delegate interactions, additional features/identities...

Added support for MUC delegate interactions, additional features/identities for MUCs, and implementation of joiningRoom/destroyingRoom in CS's MUC delegate, and use of the new identity adding functionality.  Reviewer: Armando    Pending testing.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@10121 b35dd754-fafc-0310-a699-88a17e54d16e
parent db7e648a
package org.jivesoftware.openfire.clearspace;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.component.InternalComponentManager;
import org.jivesoftware.openfire.muc.MUCEventDelegate;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.dom4j.Element;
import org.dom4j.DocumentHelper;
import java.util.HashMap;
import java.util.Map;
/**
* TODO: Comment me
* Handles checking with Clearspace regarding whether a user can join a particular chatroom (based
* on their permissions with the document/whatever the chatroom is associated with), as well as setting
* up room configurations.
*
* @author Armando Jagucki
*/
public class ClearspaceMUCEventDelegate extends MUCEventDelegate {
private String csMucDomain;
public ClearspaceMUCEventDelegate() {
csMucDomain = ClearspaceManager.MUC_SUBDOMAIN+"@"+XMPPServer.getInstance().getServerInfo().getXMPPDomain();
}
/**
* This event will be triggered when an entity joins an existing room.
* <p/>
......@@ -25,14 +35,39 @@ public class ClearspaceMUCEventDelegate extends MUCEventDelegate {
* @return true if the user is allowed to join the room.
*/
public boolean joiningRoom(String roomName, JID userjid) {
return false; // TODO: Implement
// Packet should look like:
// <iq to="clearspace.example.org" from="clearspace-conference.example.org">
// <join-check xmlns="http://jivesoftware.com/clearspace">
// <userjid>username@example.org</userjid>
// <roomjid>DOC-1234@clearspace-conference.example.org</roomjid>
// </join-check>
// </iq>
IQ query = new IQ();
query.setFrom(csMucDomain);
Element cmd = DocumentHelper.createElement("join-check");
cmd.addElement("userjid").addText(userjid.toBareJID());
cmd.addElement("roomjid").addText(roomName+"@"+csMucDomain);
query.setChildElement(cmd);
IQ result = ClearspaceManager.getInstance().query(query, 15000);
if (result == null) {
// No answer was received, assume false for security reasons.
return false;
}
if (result.getType() != IQ.Type.error) {
// No error, that indicates that we were successful and the user is permitted.
return true;
}
// No successful return, not allowed.
return false;
}
public Map<String, String> getRoomConfig(String roomName) {
Map<String, String> roomConfig = new HashMap<String, String>();
// TODO: Get the config by connecting to CS through the component
InternalComponentManager internalComponentManager = InternalComponentManager.getInstance();
// TODO: Create query packet asking for the room config and in CS create a handler for that packet
IQ query = null;
IQ result = ClearspaceManager.getInstance().query(query, 15000);
......@@ -77,6 +112,7 @@ public class ClearspaceMUCEventDelegate extends MUCEventDelegate {
* @return true if the user is allowed to destroy the room.
*/
public boolean destroyingRoom(String roomName, JID userjid) {
return false; // TODO: Implement
// We never allow destroying a room as a user, so return false always.
return false;
}
}
......@@ -404,8 +404,8 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM
muc.setMUCDelegate(new ClearspaceMUCEventDelegate());
// Set up additional features for Clearspace MUC service
muc.addExtraFeature("clearspace:service");
// Sets identity of conference service to Clearspace MUC service
muc.setDiscoIdentityType("clearspace");
// Set up additional identity of conference service to Clearspace MUC service
muc.addExtraIdentity("conference", "Clearspace Chat Service", "text");
}
// Starts the clearspace configuration task
......@@ -432,7 +432,7 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM
// Create and schedule a confi task every minute
configClearspaceTask = new ConfigClearspaceTask();
// Wait some time to start the task until Openfire has binding address
// Wait some time to start the task until Openfire has binding address
TaskEngine.getInstance().schedule(configClearspaceTask, JiveConstants.SECOND * 10, JiveConstants.MINUTE);
Log.debug("Starting configuration Clearspace task in 10 seconds.");
}
......@@ -449,7 +449,7 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM
}
try {
XMPPServerInfo serverInfo = XMPPServer.getInstance().getServerInfo();
String path = IM_URL_PREFIX + "configureComponent/";
......@@ -468,7 +468,7 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM
Log.debug("Trying to configure Clearspace with: Domain: " + serverInfo.getXMPPDomain() + ", hosts: " +
bindInterfaces.toString() + ", port: " + port);
executeRequest(POST, path, rootE.asXML());
//Done, Clearspace was configured correctly, clear the task
......@@ -529,7 +529,7 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM
} else {
bindInterfaces.add(bindInterface);
}
return bindInterfaces;
}
......@@ -839,7 +839,7 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM
* The returned packet will be handled by the server and routed to the entity that sent
* the original IQ packet. Since this method block and listen to the replied IQ packet
* then the entity that sent the original IQ packet should ignore any reply related to
* the originating IQ packet.
* the originating IQ packet.
*
* @param packet IQ packet to send.
* @param timeout milliseconds to wait before timing out.
......
......@@ -91,6 +91,13 @@ public class IQOwnerHandler {
else {
Element destroyElement = element.element("destroy");
if (destroyElement != null) {
if (((MultiUserChatServiceImpl)room.getMUCService()).getMUCDelegate() != null) {
if (!((MultiUserChatServiceImpl)room.getMUCService()).getMUCDelegate().destroyingRoom(room.getName(), role.getUserAddress())) {
// Delegate said no, reject destroy request.
throw new ForbiddenException();
}
}
room.destroyRoom(destroyElement.attributeValue("jid"), destroyElement
.elementTextTrim("reason"));
}
......
......@@ -453,6 +453,12 @@ public class LocalMUCRoom implements MUCRoom {
UserAlreadyExistsException, RoomLockedException, ForbiddenException,
RegistrationRequiredException, ConflictException, ServiceUnavailableException,
NotAcceptableException {
if (((MultiUserChatServiceImpl)mucService).getMUCDelegate() != null) {
if (!((MultiUserChatServiceImpl)mucService).getMUCDelegate().joiningRoom(this.getName(), user.getAddress())) {
// Delegate said no, reject join.
throw new UnauthorizedException();
}
}
LocalMUCRole joinRole = null;
lock.writeLock().lock();
try {
......
......@@ -214,9 +214,9 @@ public class MultiUserChatServiceImpl implements Component, MultiUserChatService
private List<String> extraDiscoFeatures = new ArrayList<String>();
/**
* Custom setting for "type" of conference service.
* Additional identities to be added to the disco response for the service.
*/
private String discoIdentityType = "text";
private List<Element> extraDiscoIdentities = new ArrayList<Element>();
/**
* Create a new group chat server.
......@@ -1103,8 +1103,7 @@ public class MultiUserChatServiceImpl implements Component, MultiUserChatService
Element identity = DocumentHelper.createElement("identity");
identity.addAttribute("category", "conference");
identity.addAttribute("name", getDescription());
identity.addAttribute("type", discoIdentityType);
identity.addAttribute("type", "text");
identities.add(identity);
// TODO: Should internationalize Public Chatroom Search, and make it configurable.
......@@ -1113,6 +1112,10 @@ public class MultiUserChatServiceImpl implements Component, MultiUserChatService
searchId.addAttribute("name", "Public Chatroom Search");
searchId.addAttribute("type", "chatroom");
identities.add(searchId);
if (!extraDiscoIdentities.isEmpty()) {
identities.addAll(extraDiscoIdentities);
}
}
else if (name != null && node == null) {
// Answer the identity of a given room
......@@ -1257,11 +1260,30 @@ public class MultiUserChatServiceImpl implements Component, MultiUserChatService
}
/**
* Sets the type of the conference service, typically "text".
* @param type The type of the conference service, "text" is the default.
* Adds an extra Disco identity to the list of identities returned for the conference service.
* @param category Category for identity. e.g. conference
* @param name Descriptive name for identity. e.g. Public Chatrooms
* @param type Type for identity. e.g. text
*/
public void setDiscoIdentityType(String type) {
discoIdentityType = type;
public void addExtraIdentity(String category, String name, String type) {
Element identity = DocumentHelper.createElement("identity");
identity.addAttribute("category", category);
identity.addAttribute("name", name);
identity.addAttribute("type", type);
extraDiscoIdentities.add(identity);
}
/**
* Removes an extra Disco identity from the list of identities returned for the conference service.
* @param name Name of identity to remove.
*/
public void removeExtraIdentity(String name) {
for (Element elem : extraDiscoIdentities) {
if (name.equals(elem.attribute("name").getStringValue())) {
extraDiscoFeatures.remove(elem);
break;
}
}
}
/**
......@@ -1272,6 +1294,14 @@ public class MultiUserChatServiceImpl implements Component, MultiUserChatService
mucEventDelegate = delegate;
}
/**
* Gets the MUC event delegate handler for this service.
* @return Handler for MUC events (delegate)
*/
public MUCEventDelegate getMUCDelegate() {
return mucEventDelegate;
}
public boolean hasInfo(String name, String node, JID senderJID) {
// Check if the service is disabled. Info is not available when disabled.
if (!isServiceEnabled()) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment