use of org.jivesoftware.openfire.roster.Roster in project Openfire by igniterealtime.
the class PrivacyList method updateList.
/**
* Sets the new list items based on the specified Element. The Element must contain
* a list of item elements.
*
* @param listElement the element containing a list of items.
* @param notify true if a provicy list modified event will be triggered.
*/
private void updateList(Element listElement, boolean notify) {
// Reset the list of items of this list
items = new ArrayList<>();
List<Element> itemsElements = listElement.elements("item");
for (Element itemElement : itemsElements) {
PrivacyItem newItem = new PrivacyItem(itemElement);
items.add(newItem);
// then ensure that the roster is available
if (newItem.isRosterRequired()) {
Roster roster = getRoster();
if (roster == null) {
Log.warn("Privacy item removed since roster of user was not found: " + userJID.getNode());
items.remove(newItem);
}
}
}
// Sort items collections
Collections.sort(items);
if (notify) {
// Trigger event that this list has been modified
PrivacyListManager.getInstance().dispatchModifiedEvent(this);
}
}
use of org.jivesoftware.openfire.roster.Roster in project Openfire by igniterealtime.
the class PresenceUpdateHandler method initSession.
/**
* A session that has transitioned to available status must be initialized.
* This includes:
* <ul>
* <li>Sending all offline presence subscription requests</li>
* <li>Sending offline messages</li>
* </ul>
*
* @param session The session being updated
* @throws UserNotFoundException If the user being updated does not exist
*/
private void initSession(ClientSession session) throws UserNotFoundException {
// Only user sessions need to be authenticated
if (userManager.isRegisteredUser(session.getAddress(), false)) {
String username = session.getAddress().getNode();
// Send pending subscription requests to user if roster service is enabled
if (RosterManager.isRosterServiceEnabled()) {
Roster roster = rosterManager.getRoster(username);
for (RosterItem item : roster.getRosterItems()) {
if (item.getRecvStatus() == RosterItem.RecvType.SUBSCRIBE) {
Presence presence = item.getSubscribeStanza();
presence.setTo(session.getAddress().asBareJID());
session.process(presence);
} else if (item.getRecvStatus() == RosterItem.RecvType.UNSUBSCRIBE) {
session.process(createSubscribePresence(item.getJid(), session.getAddress().asBareJID(), false));
}
if (item.getSubStatus() == RosterItem.SUB_TO || item.getSubStatus() == RosterItem.SUB_BOTH) {
presenceManager.probePresence(session.getAddress(), item.getJid());
}
}
}
if (session.canFloodOfflineMessages()) {
// deliver offline messages if any
Collection<OfflineMessage> messages = messageStore.getMessages(username, true);
for (Message message : messages) {
session.process(message);
}
}
}
}
use of org.jivesoftware.openfire.roster.Roster in project Openfire by igniterealtime.
the class IQRosterHandler method handleIQ.
/**
* Handles all roster queries. There are two major types of queries:
*
* <ul>
* <li>Roster remove - A forced removal of items from a roster. Roster
* removals are the only roster queries allowed to
* directly affect the roster from another user.
* </li>
* <li>Roster management - A local user looking up or updating their
* roster.
* </li>
* </ul>
*
* @param packet The update packet
* @return The reply or null if no reply
*/
@Override
public IQ handleIQ(IQ packet) throws UnauthorizedException, PacketException {
try {
IQ returnPacket;
org.xmpp.packet.Roster roster = (org.xmpp.packet.Roster) packet;
JID recipientJID = packet.getTo();
// The packet is bound for the server and must be roster management
if (recipientJID == null || recipientJID.equals(packet.getFrom().asBareJID())) {
returnPacket = manageRoster(roster);
} else {
returnPacket = IQ.createResultIQ(packet);
// The server MUST return a <forbidden/> stanza error to the client if the sender of the roster set is not authorized to update the roster
// (where typically only an authenticated resource of the account itself is authorized).
returnPacket.setError(PacketError.Condition.forbidden);
}
return returnPacket;
} catch (SharedGroupException e) {
IQ result = IQ.createResultIQ(packet);
result.setChildElement(packet.getChildElement().createCopy());
result.setError(PacketError.Condition.not_acceptable);
return result;
} catch (UnauthorizedException e) {
IQ result = IQ.createResultIQ(packet);
result.setChildElement(packet.getChildElement().createCopy());
result.setError(PacketError.Condition.not_authorized);
return result;
} catch (Exception e) {
if (e.getCause() instanceof IDNAException || e.getCause() instanceof IllegalArgumentException) {
Log.warn(LocaleUtils.getLocalizedString("admin.error") + e.getMessage());
IQ result = IQ.createResultIQ(packet);
result.setChildElement(packet.getChildElement().createCopy());
result.setError(PacketError.Condition.jid_malformed);
return result;
} else {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
IQ result = IQ.createResultIQ(packet);
result.setChildElement(packet.getChildElement().createCopy());
result.setError(PacketError.Condition.internal_server_error);
return result;
}
}
}
use of org.jivesoftware.openfire.roster.Roster in project Openfire by igniterealtime.
the class IQRosterHandler method removeItem.
/**
* Remove the roster item from the sender's roster (and possibly the recipient's).
* Actual roster removal is done in the removeItem(Roster,RosterItem) method.
*
* @param roster The sender's roster.
* @param sender The JID of the sender of the removal request
* @param item The removal item element
* @return The removed item or null, if not item has been removed.
*/
private RosterItem removeItem(org.jivesoftware.openfire.roster.Roster roster, JID sender, org.xmpp.packet.Roster.Item item) throws SharedGroupException {
JID recipient = item.getJID();
// Remove recipient from the sender's roster
RosterItem removedItem = roster.deleteRosterItem(item.getJID(), true);
// Forward set packet to the subscriber
if (localServer.isLocal(recipient)) {
// Recipient is local so let's handle it here
try {
Roster recipientRoster = userManager.getUser(recipient.getNode()).getRoster();
// Instead of deleting the sender in the recipient's roster, update it.
// https://igniterealtime.atlassian.net/browse/OF-720
RosterItem rosterItem = recipientRoster.getRosterItem(sender);
// If the receiver doesn't have subscribed yet, delete the sender from the receiver's roster, too.
if (rosterItem.getRecvStatus().equals(RosterItem.RECV_SUBSCRIBE)) {
recipientRoster.deleteRosterItem(sender, true);
} else // Otherwise only update it, so that the sender is not deleted from the receivers roster.
{
rosterItem.setAskStatus(RosterItem.ASK_NONE);
rosterItem.setRecvStatus(RosterItem.RECV_NONE);
rosterItem.setSubStatus(RosterItem.SUB_NONE);
recipientRoster.updateRosterItem(rosterItem);
}
} catch (UserNotFoundException e) {
// Do nothing
}
} else {
// Recipient is remote so we just forward the packet to them
String serverDomain = localServer.getServerInfo().getXMPPDomain();
// Check if the recipient may be hosted by this server
if (!recipient.getDomain().contains(serverDomain)) {
// TODO Implete when s2s is implemented
} else {
Packet removePacket = createRemoveForward(sender, recipient);
router.route(removePacket);
}
}
return removedItem;
}
use of org.jivesoftware.openfire.roster.Roster in project Openfire by igniterealtime.
the class PresenceSubscribeHandler method process.
@Override
public void process(Presence presence) throws PacketException {
if (presence == null) {
throw new IllegalArgumentException("Argument 'presence' cannot be null.");
}
final Presence.Type type = presence.getType();
if (type != Presence.Type.subscribe && type != Presence.Type.unsubscribe && type != Presence.Type.subscribed && type != Presence.Type.unsubscribed) {
throw new IllegalArgumentException("Packet processed by PresenceSubscribeHandler is " + "not of a subscription-related type, but: " + type);
}
// RFC-6121 paragraph 3: "When a server processes or generates an outbound presence stanza
// of type "subscribe", "subscribed", "unsubscribe", or "unsubscribed", the server MUST stamp
// the outgoing presence stanza with the bare JID <localpart@domainpart> of the sending entity,
// not the full JID <localpart@domainpart/resourcepart>."
presence.setFrom(presence.getFrom().toBareJID());
// JID and modify the 'to' address accordingly.
if (presence.getTo() != null) {
presence.setTo(presence.getTo().toBareJID());
}
final JID senderJID = presence.getFrom();
final JID recipientJID = presence.getTo();
try {
// Reject presence subscription requests sent to the local server itself.
if (recipientJID == null || recipientJID.toString().equals(serverName)) {
if (type == Presence.Type.subscribe) {
Presence reply = new Presence();
reply.setTo(senderJID);
reply.setFrom(recipientJID);
reply.setType(Presence.Type.unsubscribed);
deliverer.deliver(reply);
}
return;
}
try {
Roster senderRoster = getRoster(senderJID);
if (senderRoster != null) {
manageSub(recipientJID, true, presence, senderRoster);
}
Roster recipientRoster = getRoster(recipientJID);
boolean recipientSubChanged = false;
if (recipientRoster != null) {
recipientSubChanged = manageSub(senderJID, false, presence, recipientRoster);
}
// and the recipient user has not changed its subscription state.
if (!(type == Presence.Type.subscribed && recipientRoster != null && !recipientSubChanged)) {
// See http://tools.ietf.org/html/rfc3921#section-7 and/or OF-38
if (type == Presence.Type.subscribe && recipientRoster != null && !recipientSubChanged) {
try {
RosterItem.SubType subType = recipientRoster.getRosterItem(senderJID).getSubStatus();
if (subType == RosterItem.SUB_FROM || subType == RosterItem.SUB_BOTH) {
return;
}
} catch (UserNotFoundException e) {
// Weird case: Roster item does not exist. Should never happen
Log.error("User does not exist while trying to update roster item. " + "This should never happen (this indicates a programming " + "logic error). Processing stanza: " + presence.toString(), e);
}
}
// Try to obtain a handler for the packet based on the routes. If the handler is
// a module, the module will be able to handle the packet. If the handler is a
// Session the packet will be routed to the client. If a route cannot be found
// then the packet will be delivered based on its recipient and sender.
List<JID> jids = routingTable.getRoutes(recipientJID, null);
if (!jids.isEmpty()) {
for (JID jid : jids) {
Presence presenteToSend = presence.createCopy();
// Stamp the presence with the user's bare JID as the 'from' address,
// as required by section 8.2.5 of RFC 3921
presenteToSend.setFrom(senderJID.toBareJID());
routingTable.routePacket(jid, presenteToSend, false);
}
} else {
deliverer.deliver(presence.createCopy());
}
if (type == Presence.Type.subscribed) {
// Send the presence of the newly subscribed contact to the subscribee, by doing a presence probe.
JID prober = localServer.isLocal(recipientJID) ? recipientJID.asBareJID() : recipientJID;
if (localServer.isLocal(senderJID) && !presenceManager.canProbePresence(prober, senderJID.getNode())) {
Presence nonProbablePresence = new Presence();
nonProbablePresence.setStatus("unavailable");
nonProbablePresence.setFrom(senderJID);
nonProbablePresence.setTo(recipientJID);
presenceManager.handleProbe(nonProbablePresence);
} else {
presenceManager.probePresence(prober, senderJID);
PresenceEventDispatcher.subscribedToPresence(recipientJID, senderJID);
}
}
}
if (type == Presence.Type.unsubscribed) {
// Send unavailable presence from all of the local user's available resources
// to the remote user
presenceManager.sendUnavailableFromSessions(recipientJID, senderJID);
PresenceEventDispatcher.unsubscribedToPresence(senderJID, recipientJID);
}
} catch (SharedGroupException e) {
Presence result = presence.createCopy();
JID sender = result.getFrom();
result.setFrom(presence.getTo());
result.setTo(sender);
result.setError(PacketError.Condition.not_acceptable);
deliverer.deliver(result);
}
} catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
Aggregations