Merge "Issue #2751 ensured that room admins know real userids" into development

Former-commit-id: 181060825e [formerly 1306957f2a] [formerly e787cac9af] [formerly 181060825e [formerly 1306957f2a] [formerly e787cac9af] [formerly e963c7c4a1 [formerly e787cac9af [formerly e6feac94800c2dd82afcf42ca9f387b24514deff]]]]
Former-commit-id: e963c7c4a1
Former-commit-id: c22f8f2a07 [formerly ede24100b6] [formerly ba716a9976681eb2fe24b90c93cd383526039e18 [formerly 4dd4805e33]]
Former-commit-id: e3fccb43adb804eee9552e8406b1c63c475b17ee [formerly 3e61d24967]
Former-commit-id: 66180a8e05
This commit is contained in:
Nate Jensen 2014-03-10 09:15:39 -05:00 committed by Gerrit Code Review
commit 49d1251578
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 * Mar 5, 2012 jkorman Initial creation
* Jan 30, 2014 2698 bclement changed UserId to VenueParticipant * Jan 30, 2014 2698 bclement changed UserId to VenueParticipant
* Mar 06, 2014 2751 bclement added isAdmin()
* *
* </pre> * </pre>
* *
@ -107,8 +108,13 @@ public interface IVenueSession extends ISession {
public void sendPresence(Presence presence) throws CollaborationException; public void sendPresence(Presence presence) throws CollaborationException;
/** /**
* * @return participant id of current user
* @return
*/ */
public VenueParticipant getUserID(); 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 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; 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 * Mar 1, 2012 jkorman Initial creation
* Jan 28, 2014 2698 bclement removed getInfo, added methods to replace * Jan 28, 2014 2698 bclement removed getInfo, added methods to replace
* Jan 30, 2014 2698 bclement changed UserId to VenueParticipant * Jan 30, 2014 2698 bclement changed UserId to VenueParticipant
* Mar 06, 2014 2751 bclement added getParticipantUserid()
* *
* </pre> * </pre>
* *
@ -53,10 +56,10 @@ public interface IVenue {
/** /**
* Get the presence for a user in the session. * Get the presence for a user in the session.
* *
* @param user * @param participant
* @return * @return
*/ */
public Presence getPresence(VenueParticipant user); public Presence getPresence(VenueParticipant participant);
/** /**
* @return id of venue "name@service" * @return id of venue "name@service"
@ -78,4 +81,14 @@ public interface IVenue {
*/ */
public String getSubject(); 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.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Mode; import org.jivesoftware.smack.packet.Presence.Mode;
import org.jivesoftware.smack.packet.Presence.Type; import org.jivesoftware.smack.packet.Presence.Type;
import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.muc.Affiliate;
import org.jivesoftware.smackx.muc.MultiUserChat; 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.identity.info.IVenue;
import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter; 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; 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 * 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 * Feb 13, 2014 2751 bclement changed to use VenueParticipant handle instead of alias
* Mar 05, 2014 2798 mpduff Get Presence from MUC. * Mar 05, 2014 2798 mpduff Get Presence from MUC.
* Mar 06, 2014 2751 bclement added getParticipantUserid()
* *
* </pre> * </pre>
* *
@ -58,8 +66,13 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
*/ */
public class Venue implements IVenue { public class Venue implements IVenue {
private final static IUFStatusHandler log = UFStatus
.getHandler(Venue.class);
private final MultiUserChat muc; private final MultiUserChat muc;
private final Map<String, UserId> participantIdCache = new ConcurrentHashMap<String, UserId>();
public Venue(XMPPConnection conn, MultiUserChat muc) { public Venue(XMPPConnection conn, MultiUserChat muc) {
this.muc = muc; this.muc = muc;
} }
@ -128,4 +141,35 @@ public class Venue implements IVenue {
return rval != null ? rval : ""; 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 19, 2014 2751 bclement added isClosed()
* Feb 24, 2014 2751 bclement added validation for change leader event * Feb 24, 2014 2751 bclement added validation for change leader event
* Feb 28, 2014 2756 bclement added cleanUpHttpStorage() * Feb 28, 2014 2756 bclement added cleanUpHttpStorage()
* Mar 06, 2014 2751 bclement added calls to getParticipantUserid()
* *
* </pre> * </pre>
* *
@ -211,11 +212,11 @@ public class SharedDisplaySession extends VenueSession implements
return; return;
} }
// TODO should we use MUC private chat for this? // 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"); log.warn("Attempted to send object to peer when actual userid is unknown");
return; return;
} }
UserId userid = participant.getUserid();
SessionPayload payload = new SessionPayload(PayloadType.Command, obj); SessionPayload payload = new SessionPayload(PayloadType.Command, obj);
Message msg = new Message(userid.getFQName(), Type.normal); Message msg = new Message(userid.getFQName(), Type.normal);
msg.addExtension(payload); msg.addExtension(payload);
@ -424,6 +425,11 @@ public class SharedDisplaySession extends VenueSession implements
if (obj instanceof LeaderChangeEvent) { if (obj instanceof LeaderChangeEvent) {
validEvent = handleLeaderChange((LeaderChangeEvent) obj); 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) { if (validEvent) {
postEvent(obj); postEvent(obj);
} }
@ -601,12 +607,13 @@ public class SharedDisplaySession extends VenueSession implements
throw new CollaborationException( throw new CollaborationException(
"Only the leader can transfer leadership"); "Only the leader can transfer leadership");
} }
if (!newLeader.hasActualUserId()) { UserId actualId = getVenue().getParticipantUserid(newLeader);
if (actualId == null) {
throw new CollaborationException( throw new CollaborationException(
"Unable to grant ownership because new leader's actual userid is not known"); "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 topicOwnershipGranted = false;
boolean roomOwnershipGranted = 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 18, 2014 2751 bclement log privilege changes instead of spamming chat window
* Feb 24, 2014 2751 bclement added isRoomOwner() * Feb 24, 2014 2751 bclement added isRoomOwner()
* Mar 05, 2014 2798 mpduff Don't handle Presence, get from MUC instead.. * Mar 05, 2014 2798 mpduff Don't handle Presence, get from MUC instead..
* Mar 06, 2014 2751 bclement added isAdmin()
* *
* </pre> * </pre>
* *
@ -129,6 +130,8 @@ public class VenueSession extends BaseSession implements IVenueSession {
private Venue venue; private Venue venue;
private volatile boolean admin = false;
/** /**
* *
* @param container * @param container
@ -314,6 +317,7 @@ public class VenueSession extends BaseSession implements IVenueSession {
muc.changeSubject(data.getSubject()); muc.changeSubject(data.getSubject());
this.venue = new Venue(conn, muc); this.venue = new Venue(conn, muc);
sendPresence(CollaborationConnection.getConnection().getPresence()); sendPresence(CollaborationConnection.getConnection().getPresence());
admin = true;
} catch (XMPPException e) { } catch (XMPPException e) {
XMPPError xmppError = e.getXMPPError(); XMPPError xmppError = e.getXMPPError();
String msg; String msg;
@ -596,11 +600,13 @@ public class VenueSession extends BaseSession implements IVenueSession {
@Override @Override
public void ownershipRevoked() { public void ownershipRevoked() {
logUserEvent("You are no longer an owner of this room."); logUserEvent("You are no longer an owner of this room.");
admin = false;
} }
@Override @Override
public void ownershipGranted() { public void ownershipGranted() {
logUserEvent("You are now an owner of this room."); logUserEvent("You are now an owner of this room.");
admin = true;
} }
@Override @Override
@ -642,11 +648,13 @@ public class VenueSession extends BaseSession implements IVenueSession {
@Override @Override
public void adminRevoked() { public void adminRevoked() {
logUserEvent("You have had admin privileges revoked."); logUserEvent("You have had admin privileges revoked.");
admin = false;
} }
@Override @Override
public void adminGranted() { public void adminGranted() {
logUserEvent("You have had admin privileges granted."); logUserEvent("You have had admin privileges granted.");
admin = true;
} }
private void sendUserEvent(String message) { private void sendUserEvent(String message) {
@ -883,4 +891,15 @@ public class VenueSession extends BaseSession implements IVenueSession {
return rval; 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 12, 2014 2751 njensen Added transfer leadership and shutdown safety
* Feb 18, 2014 2751 bclement update participants list and notify on leader change * 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 * 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> * </pre>
* *
@ -850,8 +851,7 @@ public class CollaborationSessionView extends SessionView implements
public void run() { public void run() {
if (usersTable != null if (usersTable != null
&& !usersTable.getTable().isDisposed()) { && !usersTable.getTable().isDisposed()) {
usersTable.setInput(session.getVenue().getParticipants()); refreshParticipantList();
usersTable.refresh();
} }
sendParticipantSystemMessage(event.getNewLeader(), sendParticipantSystemMessage(event.getNewLeader(),
" is now leader."); " 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 18, 2014 2631 mpduff Add processJoinAlert()
* Feb 19, 2014 2751 bclement add change color icon, fix NPE when user cancels change color * 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 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> * </pre>
* *
@ -443,8 +444,7 @@ public class SessionFeedView extends SessionView {
@Override @Override
protected void participantArrived(VenueParticipant participant, protected void participantArrived(VenueParticipant participant,
String description) { String description) {
usersTable.setInput(session.getVenue().getParticipants()); refreshParticipantList();
usersTable.refresh();
} }
/** /**

View file

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