Commit ff5a11bd authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Added disco support.

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@3519 b35dd754-fafc-0310-a699-88a17e54d16e
parent 3c02e455
...@@ -43,6 +43,13 @@ ...@@ -43,6 +43,13 @@
<h1> <h1>
Broadcast Plugin Changelog Broadcast Plugin Changelog
</h1> </h1>
<p><b>1.5.0</b> -- March 06, 2006</p>
<ul>
<li>Added service discovery support.</li>
<li>Improved presence management.</li>
<li>Fixed NPE when sending packet to the service itself.</li>
</ul>
<p><b>1.4.0</b> -- March 02, 2006</p> <p><b>1.4.0</b> -- March 02, 2006</p>
<ul> <ul>
<li>Broadcast service can now be added as a roster contact.</li> <li>Broadcast service can now be added as a roster contact.</li>
......
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
<name>Broadcast</name> <name>Broadcast</name>
<description>Broadcasts messages to users.</description> <description>Broadcasts messages to users.</description>
<author>Jive Software</author> <author>Jive Software</author>
<version>1.4.0</version> <version>1.5.0</version>
<date>3/2/2006</date> <date>3/6/2006</date>
<url>http://www.jivesoftware.org</url> <url>http://www.jivesoftware.org</url>
<minServerVersion>2.4.0</minServerVersion> <minServerVersion>2.4.0</minServerVersion>
</plugin> </plugin>
\ No newline at end of file
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
package org.jivesoftware.wildfire.plugin; package org.jivesoftware.wildfire.plugin;
import org.dom4j.Element;
import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.PropertyEventDispatcher; import org.jivesoftware.util.PropertyEventDispatcher;
...@@ -124,7 +125,8 @@ public class BroadcastPlugin implements Plugin, Component, PropertyEventListener ...@@ -124,7 +125,8 @@ public class BroadcastPlugin implements Plugin, Component, PropertyEventListener
Group group = null; Group group = null;
String toNode = packet.getTo().getNode(); String toNode = packet.getTo().getNode();
// Check if user is allowed to send packet to this service[+group] // Check if user is allowed to send packet to this service[+group]
if ("all".equals(toNode)) { boolean targetAll = "all".equals(toNode);
if (targetAll) {
// See if the user is allowed to send the packet. // See if the user is allowed to send the packet.
JID address = new JID(packet.getFrom().toBareJID()); JID address = new JID(packet.getFrom().toBareJID());
if (allowedUsers.isEmpty() || allowedUsers.contains(address)) { if (allowedUsers.isEmpty() || allowedUsers.contains(address)) {
...@@ -133,136 +135,143 @@ public class BroadcastPlugin implements Plugin, Component, PropertyEventListener ...@@ -133,136 +135,143 @@ public class BroadcastPlugin implements Plugin, Component, PropertyEventListener
} }
else { else {
try { try {
group = groupManager.getGroup(toNode); if (toNode != null) {
boolean isGroupUser = group.isUser(packet.getFrom()) || group = groupManager.getGroup(toNode);
group.isUser(new JID(packet.getFrom().toBareJID())); boolean isGroupUser = group.isUser(packet.getFrom()) ||
if (disableGroupPermissions || (groupMembersAllowed && isGroupUser) || group.isUser(new JID(packet.getFrom().toBareJID()));
allowedUsers.contains(new JID(packet.getFrom().toBareJID()))) { if (disableGroupPermissions || (groupMembersAllowed && isGroupUser) ||
canProceed = true; allowedUsers.contains(new JID(packet.getFrom().toBareJID()))) {
canProceed = true;
}
} }
} }
catch (GroupNotFoundException e) { catch (GroupNotFoundException e) {
} }
} }
// Only respond to incoming messages. TODO: handle disco, presence, etc.
if (packet instanceof Message) { if (packet instanceof Message) {
// Respond to incoming messages
Message message = (Message)packet; Message message = (Message)packet;
// Check to see if trying to broadcast to all connected users. processMessage(message, targetAll, group, canProceed);
if ("all".equals(toNode)) { }
if (!canProceed) { else if (packet instanceof Presence) {
Message error = new Message(); // Respond to presence subscription request or presence probe
if (message.getID() != null) { Presence presence = (Presence) packet;
error.setID(message.getID()); processPresence(canProceed, presence);
} }
error.setError(PacketError.Condition.not_allowed); else if (packet instanceof IQ) {
error.setTo(message.getFrom()); // Handle disco packets
error.setSubject("Error sending broadcast message"); IQ iq = (IQ) packet;
error.setBody("Not allowed to send a broadcast message to " + // Ignore IQs of type ERROR or RESULT
message.getTo()); if (IQ.Type.error == iq.getType() || IQ.Type.result == iq.getType()) {
try { return;
componentManager.sendPacket(this, error); }
} processIQ(iq, targetAll, group, canProceed);
catch (Exception e) { }
componentManager.getLog().error(e); }
}
return; private void processMessage(Message message, boolean targetAll, Group group,
boolean canProceed) {
// Check to see if trying to broadcast to all connected users.
if (targetAll) {
if (!canProceed) {
Message error = new Message();
if (message.getID() != null) {
error.setID(message.getID());
} }
error.setError(PacketError.Condition.not_allowed);
error.setTo(message.getFrom());
error.setSubject("Error sending broadcast message");
error.setBody("Not allowed to send a broadcast message to " +
message.getTo());
try { try {
sessionManager.broadcast(message); componentManager.sendPacket(this, error);
} }
catch (UnauthorizedException ue) { catch (Exception e) {
Log.error(ue); componentManager.getLog().error(e);
} }
return;
} }
// See if the name is a group. try {
else { sessionManager.broadcast(message);
if (group == null) { }
// The address is not recognized so send an error message back. catch (UnauthorizedException ue) {
Message error = new Message(); Log.error(ue);
if (message.getID() != null) { }
error.setID(message.getID()); }
} // See if the name is a group.
error.setTo(message.getFrom()); else {
error.setError(PacketError.Condition.not_allowed); if (group == null) {
error.setSubject("Error sending broadcast message"); // The address is not recognized so send an error message back.
error.setBody("Address not valid: " + Message error = new Message();
message.getTo()); if (message.getID() != null) {
try { error.setID(message.getID());
componentManager.sendPacket(this, error);
}
catch (Exception e) {
componentManager.getLog().error(e);
}
} }
else if (canProceed) { error.setTo(message.getFrom());
// Broadcast message to group users. Users that are offline will get error.setError(PacketError.Condition.not_allowed);
// the message when they come back online error.setSubject("Error sending broadcast message");
for (JID userJID : group.getMembers()) { error.setBody("Address not valid: " +
Message newMessage = message.createCopy(); message.getTo());
newMessage.setTo(userJID); try {
try { componentManager.sendPacket(this, error);
componentManager.sendPacket(this, newMessage);
}
catch (Exception e) {
componentManager.getLog().error(e);
}
}
} }
else { catch (Exception e) {
// Otherwise, the address is recognized so send an error message back. componentManager.getLog().error(e);
Message error = new Message(); }
if (message.getID() != null) { }
error.setID(message.getID()); else if (canProceed) {
} // Broadcast message to group users. Users that are offline will get
error.setTo(message.getFrom()); // the message when they come back online
error.setError(PacketError.Condition.not_allowed); for (JID userJID : group.getMembers()) {
error.setSubject("Error sending broadcast message"); Message newMessage = message.createCopy();
error.setBody("Not allowed to send a broadcast message to " + newMessage.setTo(userJID);
message.getTo());
try { try {
componentManager.sendPacket(this, error); componentManager.sendPacket(this, newMessage);
} }
catch (Exception e) { catch (Exception e) {
componentManager.getLog().error(e); componentManager.getLog().error(e);
} }
} }
} }
} else {
else if (packet instanceof Presence) { // Otherwise, the address is recognized so send an error message back.
Presence presence = (Presence) packet; Message error = new Message();
try { if (message.getID() != null) {
if (!canProceed) { error.setID(message.getID());
// Send forbidden error since user is not allowed
Presence reply = new Presence();
reply.setID(presence.getID());
reply.setTo(presence.getFrom());
reply.setFrom(presence.getTo());
reply.setError(PacketError.Condition.forbidden);
componentManager.sendPacket(this, reply);
return;
} }
error.setTo(message.getFrom());
if (Presence.Type.subscribe == presence.getType()) { error.setError(PacketError.Condition.not_allowed);
// Accept all presence requests error.setSubject("Error sending broadcast message");
// Reply that the subscription request was approved error.setBody("Not allowed to send a broadcast message to " +
Presence reply = new Presence(); message.getTo());
reply.setTo(presence.getFrom()); try {
reply.setFrom(presence.getTo()); componentManager.sendPacket(this, error);
reply.setType(Presence.Type.subscribed);
componentManager.sendPacket(this, reply);
// Send that the service is available
/*reply = new Presence();
reply.setTo(presence.getFrom());
reply.setFrom(presence.getTo());
componentManager.sendPacket(this, reply);*/
} }
else if (Presence.Type.unsubscribe == presence.getType()) { catch (Exception e) {
// Send confirmation of unsubscription componentManager.getLog().error(e);
Presence reply = new Presence(); }
reply.setTo(presence.getFrom()); }
reply.setFrom(presence.getTo()); }
reply.setType(Presence.Type.unsubscribed); }
componentManager.sendPacket(this, reply);
private void processPresence(boolean canProceed, Presence presence) {
try {
if (Presence.Type.subscribe == presence.getType()) {
// Accept all presence requests if user has permissions
// Reply that the subscription request was approved or rejected
Presence reply = new Presence();
reply.setTo(presence.getFrom());
reply.setFrom(presence.getTo());
reply.setType(canProceed ? Presence.Type.subscribed : Presence.Type.unsubscribed);
componentManager.sendPacket(this, reply);
}
else if (Presence.Type.unsubscribe == presence.getType()) {
// Send confirmation of unsubscription
Presence reply = new Presence();
reply.setTo(presence.getFrom());
reply.setFrom(presence.getTo());
reply.setType(Presence.Type.unsubscribed);
componentManager.sendPacket(this, reply);
if (!canProceed) {
// Send unavailable presence of the service // Send unavailable presence of the service
reply = new Presence(); reply = new Presence();
reply.setTo(presence.getFrom()); reply.setTo(presence.getFrom());
...@@ -270,18 +279,103 @@ public class BroadcastPlugin implements Plugin, Component, PropertyEventListener ...@@ -270,18 +279,103 @@ public class BroadcastPlugin implements Plugin, Component, PropertyEventListener
reply.setType(Presence.Type.unavailable); reply.setType(Presence.Type.unavailable);
componentManager.sendPacket(this, reply); componentManager.sendPacket(this, reply);
} }
else if (Presence.Type.probe == presence.getType()) { }
// Send that the service is available else if (Presence.Type.probe == presence.getType()) {
Presence reply = new Presence(); // Send that the service is available
reply.setTo(presence.getFrom()); Presence reply = new Presence();
reply.setFrom(presence.getTo()); reply.setTo(presence.getFrom());
componentManager.sendPacket(this, reply); reply.setFrom(presence.getTo());
if (!canProceed) {
// Send forbidden error since user is not allowed
reply.setError(PacketError.Condition.forbidden);
} }
componentManager.sendPacket(this, reply);
} }
catch (ComponentException e) { }
componentManager.getLog().error(e); catch (ComponentException e) {
componentManager.getLog().error(e);
}
}
private void processIQ(IQ iq, boolean targetAll, Group group,
boolean canProceed) {
IQ reply = IQ.createResultIQ(iq);
Element childElement = iq.getChildElement();
String namespace = childElement.getNamespaceURI();
Element childElementCopy = iq.getChildElement().createCopy();
reply.setChildElement(childElementCopy);
if ("http://jabber.org/protocol/disco#info".equals(namespace)) {
if (iq.getTo().getNode() == null) {
// Return service identity and features
Element identity = childElementCopy.addElement("identity");
identity.addAttribute("category", "component");
identity.addAttribute("type", "generic");
identity.addAttribute("name", "Broadcast service");
childElementCopy.addElement("feature")
.addAttribute("var", "http://jabber.org/protocol/disco#info");
childElementCopy.addElement("feature")
.addAttribute("var", "http://jabber.org/protocol/disco#items");
}
else {
if (targetAll) {
// Return identity and features of the "all" group
Element identity = childElementCopy.addElement("identity");
identity.addAttribute("category", "component");
identity.addAttribute("type", "generic");
identity.addAttribute("name", "Broadcast all connected users");
childElementCopy.addElement("feature")
.addAttribute("var", "http://jabber.org/protocol/disco#info");
}
else if (group != null && canProceed) {
// Return identity and features of the "all" group
Element identity = childElementCopy.addElement("identity");
identity.addAttribute("category", "component");
identity.addAttribute("type", "generic");
identity.addAttribute("name", "Broadcast " + group.getName());
childElementCopy.addElement("feature")
.addAttribute("var", "http://jabber.org/protocol/disco#info");
}
else {
// Group not found or not allowed to use that group so
// answer item_not_found error
reply.setError(PacketError.Condition.item_not_found);
}
}
}
else if ("http://jabber.org/protocol/disco#items".equals(namespace)) {
if (iq.getTo().getNode() == null) {
// Return the list of groups hosted by the service that can be used by the user
Collection<Group> groups = null;
JID address = new JID(iq.getFrom().toBareJID());
if (allowedUsers.contains(address)) {
groups = groupManager.getGroups();
}
else {
groups = groupManager.getGroups(iq.getFrom());
}
for (Group userGroup : groups) {
try {
JID groupJID = new JID(userGroup.getName() + "@" + serviceName + "." +
componentManager.getServerName());
childElementCopy.addElement("item")
.addAttribute("jid", groupJID.toString());
}
catch (Exception e) {
// Group name is not valid to be used as a JID
}
}
} }
} }
else {
// Answer an error since the server can't handle the requested namespace
reply.setError(PacketError.Condition.service_unavailable);
}
try {
componentManager.sendPacket(this, reply);
}
catch (Exception e) {
componentManager.getLog().error(e);
}
} }
// Other Methods // Other Methods
......
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