Issue #2751 ensured that room admins know real userids

the server can be queried for userids by room admins
this does not update the stored participant info in muc
added cached, on-demand check for userid for participants
needed for leadership transfer


Former-commit-id: 44d161729f [formerly 44d161729f [formerly b3bf76b676b7e75559236d67c687cd5011859a8b]]
Former-commit-id: dc94769c14
Former-commit-id: ac63129ad1
This commit is contained in:
Brian Clements 2014-03-06 16:58:59 -06:00
parent 7b3b48d9b3
commit 6590587d9e
8 changed files with 125 additions and 19 deletions

View file

@ -53,6 +53,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
* ------------ ---------- ----------- --------------------------
* Mar 5, 2012 jkorman Initial creation
* Jan 30, 2014 2698 bclement changed UserId to VenueParticipant
* Mar 06, 2014 2751 bclement added isAdmin()
*
* </pre>
*
@ -107,8 +108,13 @@ public interface IVenueSession extends ISession {
public void sendPresence(Presence presence) throws CollaborationException;
/**
*
* @return
* @return participant id of current user
*/
public VenueParticipant getUserID();
/**
* @return true if current user has admin privileges in venue
*/
public boolean isAdmin();
}

View file

@ -23,6 +23,8 @@ import java.util.Collection;
import org.jivesoftware.smack.packet.Presence;
import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException;
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
/**
@ -37,6 +39,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
* Mar 1, 2012 jkorman Initial creation
* Jan 28, 2014 2698 bclement removed getInfo, added methods to replace
* Jan 30, 2014 2698 bclement changed UserId to VenueParticipant
* Mar 06, 2014 2751 bclement added getParticipantUserid()
*
* </pre>
*
@ -53,10 +56,10 @@ public interface IVenue {
/**
* Get the presence for a user in the session.
*
* @param user
* @param participant
* @return
*/
public Presence getPresence(VenueParticipant user);
public Presence getPresence(VenueParticipant participant);
/**
* @return id of venue "name@service"
@ -78,4 +81,14 @@ public interface IVenue {
*/
public String getSubject();
/**
* Attempt to find actual userid for participant. The success of this method
* may depend on admin rights in the venue.
*
* @param participant
* @return null if no userid was found
* @throws CollaborationException
*/
public UserId getParticipantUserid(VenueParticipant participant);
}

View file

@ -23,16 +23,23 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Mode;
import org.jivesoftware.smack.packet.Presence.Type;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.muc.Affiliate;
import org.jivesoftware.smackx.muc.MultiUserChat;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenue;
import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter;
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
/**
@ -50,6 +57,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
* Jan 30, 2014 2698 bclement changed UserId to VenueParticipant, getSubject never returns null
* Feb 13, 2014 2751 bclement changed to use VenueParticipant handle instead of alias
* Mar 05, 2014 2798 mpduff Get Presence from MUC.
* Mar 06, 2014 2751 bclement added getParticipantUserid()
*
* </pre>
*
@ -58,8 +66,13 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
*/
public class Venue implements IVenue {
private final static IUFStatusHandler log = UFStatus
.getHandler(Venue.class);
private final MultiUserChat muc;
private final Map<String, UserId> participantIdCache = new ConcurrentHashMap<String, UserId>();
public Venue(XMPPConnection conn, MultiUserChat muc) {
this.muc = muc;
}
@ -128,4 +141,35 @@ public class Venue implements IVenue {
return rval != null ? rval : "";
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.collaboration.comm.identity.info.IVenue#
* getParticipantUserid
* (com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant)
*/
@Override
public UserId getParticipantUserid(VenueParticipant participant) {
if (participant.hasActualUserId()) {
return participant.getUserid();
}
UserId rval = participantIdCache.get(participant.getHandle());
if (rval == null) {
try {
Collection<Affiliate> members = muc.getMembers();
for (Affiliate member : members) {
if (!org.apache.commons.lang.StringUtils.isBlank(member
.getJid())) {
UserId id = IDConverter.convertFrom(member.getJid());
participantIdCache.put(member.getNick(), id);
}
}
} catch (XMPPException e) {
log.error("Unable to get room member list from " + getName(), e);
}
rval = participantIdCache.get(participant.getHandle());
}
return rval;
}
}

View file

@ -88,6 +88,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
* Feb 19, 2014 2751 bclement added isClosed()
* Feb 24, 2014 2751 bclement added validation for change leader event
* Feb 28, 2014 2756 bclement added cleanUpHttpStorage()
* Mar 06, 2014 2751 bclement added calls to getParticipantUserid()
*
* </pre>
*
@ -211,11 +212,11 @@ public class SharedDisplaySession extends VenueSession implements
return;
}
// TODO should we use MUC private chat for this?
if (!participant.hasActualUserId()) {
UserId userid = getVenue().getParticipantUserid(participant);
if (userid == null) {
log.warn("Attempted to send object to peer when actual userid is unknown");
return;
}
UserId userid = participant.getUserid();
SessionPayload payload = new SessionPayload(PayloadType.Command, obj);
Message msg = new Message(userid.getFQName(), Type.normal);
msg.addExtension(payload);
@ -424,6 +425,11 @@ public class SharedDisplaySession extends VenueSession implements
if (obj instanceof LeaderChangeEvent) {
validEvent = handleLeaderChange((LeaderChangeEvent) obj);
}
/*
* TODO create white list of events that non-leaders can send to
* topic (ie telestration). Ignore all other events that are not
* from leader.
*/
if (validEvent) {
postEvent(obj);
}
@ -601,12 +607,13 @@ public class SharedDisplaySession extends VenueSession implements
throw new CollaborationException(
"Only the leader can transfer leadership");
}
if (!newLeader.hasActualUserId()) {
UserId actualId = getVenue().getParticipantUserid(newLeader);
if (actualId == null) {
throw new CollaborationException(
"Unable to grant ownership because new leader's actual userid is not known");
}
final String newLeaderId = newLeader.getUserid().getNormalizedId();
final String newLeaderId = actualId.getNormalizedId();
boolean topicOwnershipGranted = false;
boolean roomOwnershipGranted = false;

View file

@ -101,6 +101,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
* Feb 18, 2014 2751 bclement log privilege changes instead of spamming chat window
* Feb 24, 2014 2751 bclement added isRoomOwner()
* Mar 05, 2014 2798 mpduff Don't handle Presence, get from MUC instead..
* Mar 06, 2014 2751 bclement added isAdmin()
*
* </pre>
*
@ -129,6 +130,8 @@ public class VenueSession extends BaseSession implements IVenueSession {
private Venue venue;
private volatile boolean admin = false;
/**
*
* @param container
@ -314,6 +317,7 @@ public class VenueSession extends BaseSession implements IVenueSession {
muc.changeSubject(data.getSubject());
this.venue = new Venue(conn, muc);
sendPresence(CollaborationConnection.getConnection().getPresence());
admin = true;
} catch (XMPPException e) {
XMPPError xmppError = e.getXMPPError();
String msg;
@ -596,11 +600,13 @@ public class VenueSession extends BaseSession implements IVenueSession {
@Override
public void ownershipRevoked() {
logUserEvent("You are no longer an owner of this room.");
admin = false;
}
@Override
public void ownershipGranted() {
logUserEvent("You are now an owner of this room.");
admin = true;
}
@Override
@ -642,11 +648,13 @@ public class VenueSession extends BaseSession implements IVenueSession {
@Override
public void adminRevoked() {
logUserEvent("You have had admin privileges revoked.");
admin = false;
}
@Override
public void adminGranted() {
logUserEvent("You have had admin privileges granted.");
admin = true;
}
private void sendUserEvent(String message) {
@ -883,4 +891,15 @@ public class VenueSession extends BaseSession implements IVenueSession {
return rval;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession#isAdmin()
*/
@Override
public boolean isAdmin() {
return admin;
}
}

View file

@ -98,6 +98,7 @@ import com.raytheon.viz.ui.input.EditableManager;
* Feb 12, 2014 2751 njensen Added transfer leadership and shutdown safety
* Feb 18, 2014 2751 bclement update participants list and notify on leader change
* Feb 19, 2014 2751 bclement add change color and transfer leader icons
* Mar 06, 2014 2751 bclement moved users table refresh logic to refreshParticipantList()
*
* </pre>
*
@ -850,8 +851,7 @@ public class CollaborationSessionView extends SessionView implements
public void run() {
if (usersTable != null
&& !usersTable.getTable().isDisposed()) {
usersTable.setInput(session.getVenue().getParticipants());
usersTable.refresh();
refreshParticipantList();
}
sendParticipantSystemMessage(event.getNewLeader(),
" is now leader.");

View file

@ -70,6 +70,7 @@ import com.raytheon.uf.viz.core.icon.IconUtil;
* Feb 18, 2014 2631 mpduff Add processJoinAlert()
* Feb 19, 2014 2751 bclement add change color icon, fix NPE when user cancels change color
* Mar 05, 2014 2798 mpduff Changed how messages are processed for the feed view.
* Mar 06, 2014 2751 bclement moved users table refresh logic to refreshParticipantList()
*
* </pre>
*
@ -443,8 +444,7 @@ public class SessionFeedView extends SessionView {
@Override
protected void participantArrived(VenueParticipant participant,
String description) {
usersTable.setInput(session.getVenue().getParticipants());
usersTable.refresh();
refreshParticipantList();
}
/**

View file

@ -22,6 +22,7 @@ package com.raytheon.uf.viz.collaboration.ui.session;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -71,6 +72,7 @@ import com.raytheon.uf.viz.collaboration.comm.identity.ISession;
import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession;
import com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueParticipantEvent;
import com.raytheon.uf.viz.collaboration.comm.identity.event.ParticipantEventType;
import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenue;
import com.raytheon.uf.viz.collaboration.comm.provider.event.UserNicknameChangedEvent;
import com.raytheon.uf.viz.collaboration.comm.provider.event.VenueUserEvent;
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
@ -104,6 +106,7 @@ import com.raytheon.viz.ui.views.CaveWorkbenchPageManager;
* Feb 24, 2014 2632 mpduff Move playSound to CollaborationUtils
* Mar 05, 2014 2798 mpduff Moved processJoinAlert() call from participantHandler
* to participantArrived.
* Mar 06, 2014 2751 bclement moved users table refresh logic to refreshParticipantList()
*
* </pre>
*
@ -369,7 +372,7 @@ public class SessionView extends AbstractSessionView<VenueParticipant>
// });
if (session != null) {
usersTable.setInput(session.getVenue().getParticipants());
refreshParticipantList();
} else {
// session was null, why this would happen we don't know but this
// will somewhat gracefully let the user know a problem occurred and
@ -654,10 +657,26 @@ public class SessionView extends AbstractSessionView<VenueParticipant>
});
}
/**
* get an updated list of participants from session and refresh usersTable
*/
protected void refreshParticipantList(){
IVenue venue = session.getVenue();
Collection<VenueParticipant> participants = venue.getParticipants();
if (session.isAdmin()) {
for (VenueParticipant p : participants) {
if (!p.hasActualUserId()) {
p.setUserid(venue.getParticipantUserid(p));
}
}
}
usersTable.setInput(participants);
usersTable.refresh();
}
@Subscribe
public void userNicknameChanged(UserNicknameChangedEvent e) {
usersTable.setInput(session.getVenue().getParticipants());
usersTable.refresh();
refreshParticipantList();
}
/**
@ -667,8 +686,7 @@ public class SessionView extends AbstractSessionView<VenueParticipant>
*/
protected void participantArrived(VenueParticipant participant,
String description) {
usersTable.setInput(session.getVenue().getParticipants());
usersTable.refresh();
refreshParticipantList();
String message = description != null ? description
: "has entered the room.";
sendParticipantSystemMessage(participant, message);
@ -682,8 +700,7 @@ public class SessionView extends AbstractSessionView<VenueParticipant>
*/
protected void participantDeparted(VenueParticipant participant,
String description) {
usersTable.setInput(session.getVenue().getParticipants());
usersTable.refresh();
refreshParticipantList();
String message = description != null ? description
: "has left the room.";
sendParticipantSystemMessage(participant, message);