Checkpoint

This commit is contained in:
Zach Fox 2016-12-15 16:31:44 -08:00
parent ee3c8e6efd
commit c9dc91900f
11 changed files with 132 additions and 4 deletions

View file

@ -532,6 +532,7 @@ void DomainServer::setupNodeListAndAssignments() {
// NodeList won't be available to the settings manager when it is created, so call registerListener here
packetReceiver.registerListener(PacketType::DomainSettingsRequest, &_settingsManager, "processSettingsRequestPacket");
packetReceiver.registerListener(PacketType::NodeKickRequest, &_settingsManager, "processNodeKickRequestPacket");
packetReceiver.registerListener(PacketType::UsernameFromIDRequest, &_settingsManager, "processUsernameFromIDRequestPacket");
// register the gatekeeper for the packets it needs to receive
packetReceiver.registerListener(PacketType::DomainConnectRequest, &_gatekeeper, "processConnectRequestPacket");

View file

@ -748,6 +748,57 @@ void DomainServerSettingsManager::processNodeKickRequestPacket(QSharedPointer<Re
}
}
void DomainServerSettingsManager::processUsernameFromIDRequestPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
// before we do any processing on this packet make sure it comes from a node that is allowed to kick
if (sendingNode->getCanKick()) {
// pull the UUID being kicked from the packet
QUuid nodeUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
if (!nodeUUID.isNull() && nodeUUID != sendingNode->getUUID()) {
// make sure we actually have a node with this UUID
auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
auto matchingNode = limitedNodeList->nodeWithUUID(nodeUUID);
if (matchingNode) {
// we have a matching node, time to decide how to store updated permissions for this node
NodePermissionsPointer destinationPermissions;
QString verifiedUsername = matchingNode->getPermissions().getVerifiedUserName();
bool newPermissions = false;
if (!verifiedUsername.isEmpty()) {
QByteArray printableVerifiedUsername = qPrintable(verifiedUsername);
// setup the packet
auto usernameFromIDRequestPacket = NLPacket::create(PacketType::UsernameFromIDRequest, NUM_BYTES_RFC4122_UUID + printableVerifiedUsername.length(), true);
// write the node ID to the packet
usernameFromIDRequestPacket->write(nodeUUID.toRfc4122());
// write the username to the packet
usernameFromIDRequestPacket->write(printableVerifiedUsername);
auto nodeList = DependencyManager::get<LimitedNodeList>();
nodeList->sendPacket(std::move(usernameFromIDRequestPacket), message->getSenderSockAddr());
}
}
else {
qWarning() << "Node username request received for unknown node. Refusing to process.";
}
}
else {
// this isn't a UUID we can use
qWarning() << "Node username request received for invalid node ID. Refusing to process.";
}
}
else {
qWarning() << "Refusing to process a username request packet from node" << uuidStringWithoutCurlyBraces(sendingNode->getUUID())
<< "that does not have kick permissions.";
}
}
QStringList DomainServerSettingsManager::getAllNames() const {
QStringList result;
foreach (auto key, _agentPermissions.keys()) {

View file

@ -113,6 +113,7 @@ public slots:
private slots:
void processSettingsRequestPacket(QSharedPointer<ReceivedMessage> message);
void processNodeKickRequestPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
void processUsernameFromIDRequestPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
private:
QStringList _argumentList;

View file

@ -72,6 +72,11 @@ Rectangle {
table.selection.deselect(userIndex);
}
break;
case 'updateUsername':
var userId = message.params[0];
var userName = message.params[1];
var userIndex = findSessionIndex(userId);
table.get(userIndex).itemCell.nameCard.userName = userName;
default:
console.log('Unrecognized message:', JSON.stringify(message));
}

View file

@ -127,6 +127,7 @@ NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort)
packetReceiver.registerListener(PacketType::ICEPingReply, &_domainHandler, "processICEPingReplyPacket");
packetReceiver.registerListener(PacketType::DomainServerPathResponse, this, "processDomainServerPathResponse");
packetReceiver.registerListener(PacketType::DomainServerRemovedNode, this, "processDomainServerRemovedNode");
packetReceiver.registerListener(PacketType::UsernameFromIDRequest, this, "processUsernameFromIDRequestPacket");
}
qint64 NodeList::sendStats(QJsonObject statsObject, HifiSockAddr destination) {
@ -889,3 +890,39 @@ void NodeList::muteNodeBySessionID(const QUuid& nodeID) {
}
}
void NodeList::requestUsernameFromSessionID(const QUuid& nodeID) {
// send a request to domain-server to get the username associated with the given session ID
if (!nodeID.isNull()) {
if (getThisNodeCanKick()) {
// setup the packet
auto usernameFromIDRequestPacket = NLPacket::create(PacketType::UsernameFromIDRequest, NUM_BYTES_RFC4122_UUID, true);
// write the node ID to the packet
usernameFromIDRequestPacket->write(nodeID.toRfc4122());
qDebug() << "Sending packet to get username of node" << uuidStringWithoutCurlyBraces(nodeID);
sendPacket(std::move(usernameFromIDRequestPacket), _domainHandler.getSockAddr());
}
else {
qWarning() << "You do not have permissions to kick in this domain."
<< "Request to get the username of node" << uuidStringWithoutCurlyBraces(nodeID) << "will not be sent";
}
}
else {
qWarning() << "NodeList::requestUsernameFromSessionID called with an invalid ID.";
}
}
void NodeList::processUsernameFromIDRequestPacket(QSharedPointer<ReceivedMessage> message) {
// read the UUID from the packet
// read the UUID from the packet, remove it if it exists
QUuid nodeUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
// read the username from the packet
QString username = message->readString();
emit usernameFromID(nodeUUID, username);
}

View file

@ -81,6 +81,8 @@ public:
void kickNodeBySessionID(const QUuid& nodeID);
void muteNodeBySessionID(const QUuid& nodeID);
void requestUsernameFromSessionID(const QUuid& nodeID);
void processUsernameFromIDRequestPacket(QSharedPointer<ReceivedMessage> message);
public slots:
void reset();
@ -108,6 +110,7 @@ signals:
void receivedDomainServerList();
void ignoredNode(const QUuid& nodeID);
void ignoreRadiusEnabledChanged(bool isIgnored);
void usernameFromID(QUuid& nodeID, QString& username);
private slots:
void stopKeepalivePingTimer();

View file

@ -26,8 +26,8 @@ const QSet<PacketType> NON_VERIFIED_PACKETS = QSet<PacketType>()
<< PacketType::NodeJsonStats << PacketType::EntityQuery
<< PacketType::OctreeDataNack << PacketType::EntityEditNack
<< PacketType::DomainListRequest << PacketType::StopNode
<< PacketType::DomainDisconnectRequest << PacketType::NodeKickRequest
<< PacketType::NodeMuteRequest;
<< PacketType::DomainDisconnectRequest << PacketType::UsernameFromIDRequest
<< PacketType::NodeKickRequest << PacketType::NodeMuteRequest;
const QSet<PacketType> NON_SOURCED_PACKETS = QSet<PacketType>()
<< PacketType::StunResponse << PacketType::CreateAssignment << PacketType::RequestAssignment

View file

@ -101,7 +101,8 @@ public:
NodeKickRequest,
NodeMuteRequest,
RadiusIgnoreRequest,
LAST_PACKET_TYPE = RadiusIgnoreRequest
UsernameFromIDRequest,
LAST_PACKET_TYPE = UsernameFromIDRequest
};
};

View file

@ -18,6 +18,7 @@ UsersScriptingInterface::UsersScriptingInterface() {
auto nodeList = DependencyManager::get<NodeList>();
connect(nodeList.data(), &LimitedNodeList::canKickChanged, this, &UsersScriptingInterface::canKickChanged);
connect(nodeList.data(), &NodeList::ignoreRadiusEnabledChanged, this, &UsersScriptingInterface::ignoreRadiusEnabledChanged);
connect(nodeList.data(), &NodeList::usernameFromID, this, &UsersScriptingInterface::usernameFromID);
}
void UsersScriptingInterface::ignore(const QUuid& nodeID) {
@ -35,6 +36,11 @@ void UsersScriptingInterface::mute(const QUuid& nodeID) {
DependencyManager::get<NodeList>()->muteNodeBySessionID(nodeID);
}
void UsersScriptingInterface::requestUsernameFromID(const QUuid& nodeID) {
// ask the Domain Server via the NodeList for the username associated with the given session ID
DependencyManager::get<NodeList>()->requestUsernameFromSessionID(nodeID);
}
bool UsersScriptingInterface::getCanKick() {
// ask the NodeList to return our ability to kick
return DependencyManager::get<NodeList>()->getThisNodeCanKick();

View file

@ -51,6 +51,13 @@ public slots:
*/
void mute(const QUuid& nodeID);
/**jsdoc
* Returns a string containing the username associated with the given Avatar UUID
* @function Users.getUsernameFromID
* @param {nodeID} nodeID The node or session ID of the user whose username you want.
*/
void requestUsernameFromID(const QUuid& nodeID);
/**jsdoc
* Returns `true` if the DomainServer will allow this Node/Avatar to make kick
* @function Users.getCanKick
@ -92,6 +99,12 @@ signals:
* @function Users.enteredIgnoreRadius
*/
void enteredIgnoreRadius();
/**jsdoc
* Notifies scripts of the username associated with a UUID.
* @function Users.enteredIgnoreRadius
*/
void usernameFromID(QUuid& nodeID, QString& username);
};

View file

@ -118,9 +118,12 @@ function populateUserList() {
var avatar = AvatarList.getAvatar(id);
var avatarPalDatum = {
displayName: avatar.displayName || ('anonymous ' + counter++),
userName: "fakeAcct" + (id || "Me"),
userName: Users.canKick ? 'Obtaining username...' : '',
sessionId: id || ''
};
if (Users.canKick) {
Users.getUsernameFromID(id);
}
data.push(avatarPalDatum);
if (id) { // No overlay for ourself.
addAvatarNode(id);
@ -129,6 +132,13 @@ function populateUserList() {
});
pal.sendToQml({method: 'users', params: data});
}
function usernameFromID(id, username) {
var data = { id: id, username: username };
print('Username Data:', JSON.stringify(data));
pal.sendToQml({ method: 'updateUsername', params: data });
}
var pingPong = true;
function updateOverlays() {
var eye = Camera.position;