org.jivesoftware.openfire.handler.IQPrivateHandler Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2004-2008 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.openfire.handler;
import org.dom4j.Element;
import org.jivesoftware.openfire.IQHandlerInfo;
import org.jivesoftware.openfire.PacketException;
import org.jivesoftware.openfire.PrivateStorage;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.disco.ServerFeaturesProvider;
import org.xmpp.packet.IQ;
import org.xmpp.packet.PacketError;
import java.util.Collections;
import java.util.Iterator;
/**
* Implements the TYPE_IQ jabber:iq:private protocol. Clients
* use this protocol to store and retrieve arbitrary application
* configuration information. Using the server for setting storage
* allows client configurations to follow users where ever they go.
*
* A 'get' query retrieves any stored data.
* A 'set' query stores new data.
*
*
* Currently an empty implementation to allow usage with normal
* clients. Future implementation needed.
*
* Assumptions
* This handler assumes that the request is addressed to the server.
* An appropriate TYPE_IQ tag matcher should be placed in front of this
* one to route TYPE_IQ requests not addressed to the server to
* another channel (probably for direct delivery to the recipient).
* Warning
* There should be a way of determining whether a session has
* authorization to access this feature. I'm not sure it is a good
* idea to do authorization in each handler. It would be nice if
* the framework could assert authorization policies across channels.
*
* @author Iain Shigeoka
*/
public class IQPrivateHandler extends IQHandler implements ServerFeaturesProvider {
private IQHandlerInfo info;
private PrivateStorage privateStorage = null;
public IQPrivateHandler() {
super("XMPP Private Storage Handler");
info = new IQHandlerInfo("query", "jabber:iq:private");
}
@Override
public IQ handleIQ(IQ packet) throws UnauthorizedException, PacketException {
IQ replyPacket;
Element child = packet.getChildElement();
Element dataElement = (Element) child.elementIterator().next();
if (dataElement != null) {
if (IQ.Type.get.equals(packet.getType())) {
replyPacket = IQ.createResultIQ(packet);
Element dataStored = privateStorage.get(packet.getFrom().getNode(), dataElement);
dataStored.setParent(null);
child.remove(dataElement);
child.setParent(null);
replyPacket.setChildElement(child);
child.add(dataStored);
}
else {
replyPacket = IQ.createResultIQ(packet);
if (privateStorage.isEnabled()) {
privateStorage.add(packet.getFrom().getNode(), dataElement);
} else {
replyPacket.setChildElement(packet.getChildElement().createCopy());
replyPacket.setError(PacketError.Condition.service_unavailable);
}
}
}
else {
replyPacket = IQ.createResultIQ(packet);
replyPacket.setChildElement("query", "jabber:iq:private");
}
return replyPacket;
}
@Override
public void initialize(XMPPServer server) {
super.initialize(server);
privateStorage = server.getPrivateStorage();
}
@Override
public IQHandlerInfo getInfo() {
return info;
}
@Override
public Iterator getFeatures() {
return Collections.singleton("jabber:iq:private").iterator();
}
}