mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-22 14:22:05 +01:00
IoT: Prevent control/read-out from non friends
and make the behavior configurable.
This commit is contained in:
parent
6d74d0383c
commit
da58b20b53
4 changed files with 69 additions and 33 deletions
|
@ -16,27 +16,62 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.iot;
|
package org.jivesoftware.smackx.iot;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.logging.Logger;
|
||||||
import java.util.WeakHashMap;
|
|
||||||
|
|
||||||
import org.jivesoftware.smack.Manager;
|
import org.jivesoftware.smack.Manager;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.packet.IQ.Type;
|
||||||
|
import org.jivesoftware.smackx.iot.provisioning.IoTProvisioningManager;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
public final class IoTManager extends Manager {
|
public abstract class IoTManager extends Manager {
|
||||||
|
|
||||||
private static final Map<XMPPConnection, IoTManager> INSTANCES = new WeakHashMap<>();
|
private static final Logger LOGGER = Logger.getLogger(IoTManager.class.getName());
|
||||||
|
|
||||||
public static synchronized IoTManager getInstanceFor(XMPPConnection connection) {
|
private final IoTProvisioningManager ioTProvisioningManager;
|
||||||
IoTManager manager = INSTANCES.get(connection);
|
|
||||||
if (manager == null) {
|
|
||||||
manager = new IoTManager(connection);
|
|
||||||
INSTANCES.put(connection, manager);
|
|
||||||
}
|
|
||||||
return manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IoTManager(XMPPConnection connection) {
|
private boolean allowNonFriends;
|
||||||
|
|
||||||
|
protected IoTManager(XMPPConnection connection) {
|
||||||
super(connection);
|
super(connection);
|
||||||
|
|
||||||
|
ioTProvisioningManager = IoTProvisioningManager.getInstanceFor(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether or not non friends should be able to use the services provided by this manager. Those non-friend
|
||||||
|
* entities still need to know the full JID for IQ based requests.
|
||||||
|
*
|
||||||
|
* @param allowNonFriends true to allow everyone to use the services.
|
||||||
|
*/
|
||||||
|
public void setAllowNonFriends(boolean allowNonFriends) {
|
||||||
|
this.allowNonFriends = allowNonFriends;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isAllowed(Jid jid) {
|
||||||
|
if (allowNonFriends) return true;
|
||||||
|
|
||||||
|
return ioTProvisioningManager.isMyFriend(jid);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract class IoTIqRequestHandler extends AbstractIqRequestHandler {
|
||||||
|
|
||||||
|
protected IoTIqRequestHandler(String element, String namespace, Type type, Mode mode) {
|
||||||
|
super(element, namespace, type, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final IQ handleIQRequest(IQ iqRequest) {
|
||||||
|
if (!isAllowed(iqRequest.getFrom())) {
|
||||||
|
LOGGER.warning("Ignoring IQ request " + iqRequest);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handleIoTIqRequest(iqRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract IQ handleIoTIqRequest(IQ iqRequest);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,14 +22,13 @@ import java.util.Map;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.jivesoftware.smack.Manager;
|
|
||||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||||
import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
|
|
||||||
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
|
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smackx.iot.IoTManager;
|
||||||
import org.jivesoftware.smackx.iot.Thing;
|
import org.jivesoftware.smackx.iot.Thing;
|
||||||
import org.jivesoftware.smackx.iot.control.element.IoTSetRequest;
|
import org.jivesoftware.smackx.iot.control.element.IoTSetRequest;
|
||||||
import org.jivesoftware.smackx.iot.control.element.IoTSetResponse;
|
import org.jivesoftware.smackx.iot.control.element.IoTSetResponse;
|
||||||
|
@ -43,7 +42,7 @@ import org.jxmpp.jid.FullJid;
|
||||||
* @author Florian Schmaus {@literal <flo@geekplace.eu>}
|
* @author Florian Schmaus {@literal <flo@geekplace.eu>}
|
||||||
* @see <a href="http://xmpp.org/extensions/xep-0325.html">XEP-0323: Internet of Things - Control</a>
|
* @see <a href="http://xmpp.org/extensions/xep-0325.html">XEP-0323: Internet of Things - Control</a>
|
||||||
*/
|
*/
|
||||||
public final class IoTControlManager extends Manager {
|
public final class IoTControlManager extends IoTManager {
|
||||||
|
|
||||||
private static final Map<XMPPConnection, IoTControlManager> INSTANCES = new WeakHashMap<>();
|
private static final Map<XMPPConnection, IoTControlManager> INSTANCES = new WeakHashMap<>();
|
||||||
|
|
||||||
|
@ -66,9 +65,10 @@ public final class IoTControlManager extends Manager {
|
||||||
|
|
||||||
private IoTControlManager(XMPPConnection connection) {
|
private IoTControlManager(XMPPConnection connection) {
|
||||||
super(connection);
|
super(connection);
|
||||||
connection.registerIQRequestHandler(new AbstractIqRequestHandler(IoTSetRequest.ELEMENT, IoTSetRequest.NAMESPACE, IQ.Type.set, Mode.async) {
|
|
||||||
|
connection.registerIQRequestHandler(new IoTIqRequestHandler(IoTSetRequest.ELEMENT, IoTSetRequest.NAMESPACE, IQ.Type.set, Mode.async) {
|
||||||
@Override
|
@Override
|
||||||
public IQ handleIQRequest(IQ iqRequest) {
|
public IQ handleIoTIqRequest(IQ iqRequest) {
|
||||||
// TODO Lookup thing and provide data.
|
// TODO Lookup thing and provide data.
|
||||||
IoTSetRequest iotSetRequest = (IoTSetRequest) iqRequest;
|
IoTSetRequest iotSetRequest = (IoTSetRequest) iqRequest;
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ public final class IoTControlManager extends Manager {
|
||||||
*
|
*
|
||||||
* @param jid
|
* @param jid
|
||||||
* @param data
|
* @param data
|
||||||
* @return
|
* @return a IoTSetResponse
|
||||||
* @throws NoResponseException
|
* @throws NoResponseException
|
||||||
* @throws XMPPErrorException
|
* @throws XMPPErrorException
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
|
|
|
@ -26,7 +26,6 @@ import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.ConnectionCreationListener;
|
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||||
import org.jivesoftware.smack.Manager;
|
|
||||||
import org.jivesoftware.smack.PacketCollector;
|
import org.jivesoftware.smack.PacketCollector;
|
||||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||||
|
@ -34,10 +33,10 @@ import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.XMPPConnectionRegistry;
|
import org.jivesoftware.smack.XMPPConnectionRegistry;
|
||||||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||||
import org.jivesoftware.smack.filter.StanzaFilter;
|
import org.jivesoftware.smack.filter.StanzaFilter;
|
||||||
import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
|
|
||||||
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
|
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
|
import org.jivesoftware.smackx.iot.IoTManager;
|
||||||
import org.jivesoftware.smackx.iot.Thing;
|
import org.jivesoftware.smackx.iot.Thing;
|
||||||
import org.jivesoftware.smackx.iot.data.element.IoTDataField;
|
import org.jivesoftware.smackx.iot.data.element.IoTDataField;
|
||||||
import org.jivesoftware.smackx.iot.data.element.IoTDataReadOutAccepted;
|
import org.jivesoftware.smackx.iot.data.element.IoTDataReadOutAccepted;
|
||||||
|
@ -53,7 +52,7 @@ import org.jxmpp.jid.EntityFullJid;
|
||||||
* @author Florian Schmaus {@literal <flo@geekplace.eu>}
|
* @author Florian Schmaus {@literal <flo@geekplace.eu>}
|
||||||
* @see <a href="http://xmpp.org/extensions/xep-0323.html">XEP-0323: Internet of Things - Sensor Data</a>
|
* @see <a href="http://xmpp.org/extensions/xep-0323.html">XEP-0323: Internet of Things - Sensor Data</a>
|
||||||
*/
|
*/
|
||||||
public final class IoTDataManager extends Manager {
|
public final class IoTDataManager extends IoTManager {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(IoTDataManager.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(IoTDataManager.class.getName());
|
||||||
|
|
||||||
|
@ -89,13 +88,10 @@ public final class IoTDataManager extends Manager {
|
||||||
|
|
||||||
private IoTDataManager(XMPPConnection connection) {
|
private IoTDataManager(XMPPConnection connection) {
|
||||||
super(connection);
|
super(connection);
|
||||||
|
connection.registerIQRequestHandler(new IoTIqRequestHandler(IoTDataRequest.ELEMENT,
|
||||||
connection.registerIQRequestHandler(new AbstractIqRequestHandler(IoTDataRequest.ELEMENT,
|
|
||||||
IoTDataRequest.NAMESPACE, IQ.Type.get, Mode.async) {
|
IoTDataRequest.NAMESPACE, IQ.Type.get, Mode.async) {
|
||||||
@Override
|
@Override
|
||||||
public IQ handleIQRequest(IQ iqRequest) {
|
public IQ handleIoTIqRequest(IQ iqRequest) {
|
||||||
// TODO Verify that iqRequest.from is friend?
|
|
||||||
|
|
||||||
final IoTDataRequest dataRequest = (IoTDataRequest) iqRequest;
|
final IoTDataRequest dataRequest = (IoTDataRequest) iqRequest;
|
||||||
|
|
||||||
if (!dataRequest.isMomentary()) {
|
if (!dataRequest.isMomentary()) {
|
||||||
|
|
|
@ -350,6 +350,13 @@ public final class IoTProvisioningManager extends Manager {
|
||||||
return isFriend;
|
return isFriend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean iAmFriendOf(BareJid otherJid) {
|
||||||
|
RosterEntry entry = roster.getEntry(otherJid);
|
||||||
|
if (entry == null) return false;
|
||||||
|
|
||||||
|
return entry.canSeeHisPresence();
|
||||||
|
}
|
||||||
|
|
||||||
public void sendFriendshipRequest(BareJid bareJid) throws NotConnectedException, InterruptedException {
|
public void sendFriendshipRequest(BareJid bareJid) throws NotConnectedException, InterruptedException {
|
||||||
Presence presence = new Presence(Presence.Type.subscribe);
|
Presence presence = new Presence(Presence.Type.subscribe);
|
||||||
presence.setTo(bareJid);
|
presence.setTo(bareJid);
|
||||||
|
@ -360,19 +367,17 @@ public final class IoTProvisioningManager extends Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendFriendshipRequestIfRequired(BareJid jid) throws NotConnectedException, InterruptedException {
|
public void sendFriendshipRequestIfRequired(BareJid jid) throws NotConnectedException, InterruptedException {
|
||||||
RosterEntry entry = roster.getEntry(jid);
|
if (iAmFriendOf(jid)) return;
|
||||||
if (entry != null && entry.canSeeHisPresence()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sendFriendshipRequest(jid);
|
sendFriendshipRequest(jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBefriended(Jid friendInQuestion) {
|
public boolean isMyFriend(Jid friendInQuestion) {
|
||||||
return roster.isSubscribedToMyPresence(friendInQuestion);
|
return roster.isSubscribedToMyPresence(friendInQuestion);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unfriend(Jid friend) throws NotConnectedException, InterruptedException {
|
public void unfriend(Jid friend) throws NotConnectedException, InterruptedException {
|
||||||
if (isBefriended(friend)) {
|
if (isMyFriend(friend)) {
|
||||||
Presence presence = new Presence(Presence.Type.unsubscribed);
|
Presence presence = new Presence(Presence.Type.unsubscribed);
|
||||||
presence.setTo(friend);
|
presence.setTo(friend);
|
||||||
connection().sendStanza(presence);
|
connection().sendStanza(presence);
|
||||||
|
|
Loading…
Reference in a new issue