mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 18:50:00 +02:00
add auth to assignment-client, fix refresh of static assignments
This commit is contained in:
parent
fcb36f0aca
commit
27c779666b
8 changed files with 96 additions and 34 deletions
|
@ -6,9 +6,11 @@
|
||||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <QtCore/QProcess>
|
||||||
#include <QtCore/QThread>
|
#include <QtCore/QThread>
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
|
|
||||||
|
#include <AccountManager.h>
|
||||||
#include <Assignment.h>
|
#include <Assignment.h>
|
||||||
#include <Logging.h>
|
#include <Logging.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
|
@ -91,6 +93,10 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
|
||||||
|
|
||||||
// connect our readPendingDatagrams method to the readyRead() signal of the socket
|
// connect our readPendingDatagrams method to the readyRead() signal of the socket
|
||||||
connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClient::readPendingDatagrams);
|
connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClient::readPendingDatagrams);
|
||||||
|
|
||||||
|
// connections to AccountManager for authentication
|
||||||
|
connect(&AccountManager::getInstance(), &AccountManager::authRequired,
|
||||||
|
this, &AssignmentClient::handleAuthenticationRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssignmentClient::sendAssignmentRequest() {
|
void AssignmentClient::sendAssignmentRequest() {
|
||||||
|
@ -158,6 +164,30 @@ void AssignmentClient::readPendingDatagrams() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssignmentClient::handleAuthenticationRequest() {
|
||||||
|
const QString DATA_SERVER_USERNAME_ENV = "HIFI_AC_USERNAME";
|
||||||
|
const QString DATA_SERVER_PASSWORD_ENV = "HIFI_AC_PASSWORD";
|
||||||
|
|
||||||
|
// this node will be using an authentication server, let's make sure we have a username/password
|
||||||
|
QProcessEnvironment sysEnvironment = QProcessEnvironment::systemEnvironment();
|
||||||
|
|
||||||
|
QString username = sysEnvironment.value(DATA_SERVER_USERNAME_ENV);
|
||||||
|
QString password = sysEnvironment.value(DATA_SERVER_PASSWORD_ENV);
|
||||||
|
|
||||||
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
|
|
||||||
|
if (!username.isEmpty() && !password.isEmpty()) {
|
||||||
|
// ask the account manager to log us in from the env variables
|
||||||
|
accountManager.requestAccessToken(username, password);
|
||||||
|
} else {
|
||||||
|
qDebug() << "Authentication was requested against" << qPrintable(accountManager.getRootURL().toString())
|
||||||
|
<< "but both or one of" << qPrintable(DATA_SERVER_USERNAME_ENV)
|
||||||
|
<< "/" << qPrintable(DATA_SERVER_PASSWORD_ENV) << "are not set. Unable to authenticate.";
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AssignmentClient::assignmentCompleted() {
|
void AssignmentClient::assignmentCompleted() {
|
||||||
// reset the logging target to the the CHILD_TARGET_NAME
|
// reset the logging target to the the CHILD_TARGET_NAME
|
||||||
Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME);
|
Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME);
|
||||||
|
@ -175,5 +205,6 @@ void AssignmentClient::assignmentCompleted() {
|
||||||
// reset our NodeList by switching back to unassigned and clearing the list
|
// reset our NodeList by switching back to unassigned and clearing the list
|
||||||
nodeList->setOwnerType(NodeType::Unassigned);
|
nodeList->setOwnerType(NodeType::Unassigned);
|
||||||
nodeList->reset();
|
nodeList->reset();
|
||||||
|
nodeList->getDomainInfo().reset();
|
||||||
nodeList->resetNodeInterestSet();
|
nodeList->resetNodeInterestSet();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ private slots:
|
||||||
void sendAssignmentRequest();
|
void sendAssignmentRequest();
|
||||||
void readPendingDatagrams();
|
void readPendingDatagrams();
|
||||||
void assignmentCompleted();
|
void assignmentCompleted();
|
||||||
|
void handleAuthenticationRequest();
|
||||||
private:
|
private:
|
||||||
Assignment _requestAssignment;
|
Assignment _requestAssignment;
|
||||||
ThreadedAssignment* _currentAssignment;
|
ThreadedAssignment* _currentAssignment;
|
||||||
|
|
|
@ -55,23 +55,24 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_nodeAuthenticationURL.isEmpty()) {
|
if (!_nodeAuthenticationURL.isEmpty()) {
|
||||||
// this domain-server will be using an authentication server, let's make sure we have a username/password
|
|
||||||
QProcessEnvironment sysEnvironment = QProcessEnvironment::systemEnvironment();
|
|
||||||
|
|
||||||
const QString DATA_SERVER_USERNAME_ENV = "HIFI_DS_USERNAME";
|
const QString DATA_SERVER_USERNAME_ENV = "HIFI_DS_USERNAME";
|
||||||
const QString DATA_SERVER_PASSWORD_ENV = "HIFI_DS_PASSWORD";
|
const QString DATA_SERVER_PASSWORD_ENV = "HIFI_DS_PASSWORD";
|
||||||
|
|
||||||
|
// this node will be using an authentication server, let's make sure we have a username/password
|
||||||
|
QProcessEnvironment sysEnvironment = QProcessEnvironment::systemEnvironment();
|
||||||
|
|
||||||
QString username = sysEnvironment.value(DATA_SERVER_USERNAME_ENV);
|
QString username = sysEnvironment.value(DATA_SERVER_USERNAME_ENV);
|
||||||
QString password = sysEnvironment.value(DATA_SERVER_PASSWORD_ENV);
|
QString password = sysEnvironment.value(DATA_SERVER_PASSWORD_ENV);
|
||||||
|
|
||||||
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
|
accountManager.setRootURL(_nodeAuthenticationURL);
|
||||||
|
|
||||||
if (!username.isEmpty() && !password.isEmpty()) {
|
if (!username.isEmpty() && !password.isEmpty()) {
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
|
||||||
accountManager.setRootURL(_nodeAuthenticationURL);
|
|
||||||
|
|
||||||
// TODO: failure case for not receiving a token
|
|
||||||
accountManager.requestAccessToken(username, password);
|
|
||||||
|
|
||||||
connect(&accountManager, &AccountManager::loginComplete, this, &DomainServer::requestCreationFromDataServer);
|
connect(&accountManager, &AccountManager::loginComplete, this, &DomainServer::requestCreationFromDataServer);
|
||||||
|
|
||||||
|
// ask the account manager to log us in from the env variables
|
||||||
|
accountManager.requestAccessToken(username, password);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Authentication was requested against" << qPrintable(_nodeAuthenticationURL.toString())
|
qDebug() << "Authentication was requested against" << qPrintable(_nodeAuthenticationURL.toString())
|
||||||
<< "but both or one of" << qPrintable(DATA_SERVER_USERNAME_ENV)
|
<< "but both or one of" << qPrintable(DATA_SERVER_USERNAME_ENV)
|
||||||
|
@ -82,6 +83,7 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// auth is not requested for domain-server, setup NodeList and assignments now
|
// auth is not requested for domain-server, setup NodeList and assignments now
|
||||||
setupNodeListAndAssignments();
|
setupNodeListAndAssignments();
|
||||||
|
@ -326,27 +328,28 @@ void DomainServer::addNodeToNodeListAndConfirmConnection(const QByteArray& packe
|
||||||
|
|
||||||
int numPreInterestBytes = parseNodeDataFromByteArray(nodeType, publicSockAddr, localSockAddr, packet, senderSockAddr);
|
int numPreInterestBytes = parseNodeDataFromByteArray(nodeType, publicSockAddr, localSockAddr, packet, senderSockAddr);
|
||||||
|
|
||||||
QUuid nodeUUID = uuidFromPacketHeader(packet);
|
QUuid assignmentUUID = uuidFromPacketHeader(packet);
|
||||||
SharedAssignmentPointer matchingAssignment;
|
SharedAssignmentPointer matchingAssignment;
|
||||||
|
|
||||||
if (!nodeUUID.isNull() && (matchingAssignment = matchingStaticAssignmentForCheckIn(nodeUUID, nodeType))) {
|
if (!assignmentUUID.isNull() && (matchingAssignment = matchingStaticAssignmentForCheckIn(assignmentUUID, nodeType))
|
||||||
|
&& matchingAssignment) {
|
||||||
// this is an assigned node, make sure the UUID sent is for an assignment we're actually trying to give out
|
// this is an assigned node, make sure the UUID sent is for an assignment we're actually trying to give out
|
||||||
nodeUUID = uuidFromPacketHeader(packet);
|
|
||||||
|
|
||||||
if (matchingAssignment) {
|
// remove the matching assignment from the assignment queue so we don't take the next check in
|
||||||
// this was a newly added node with a matching assignment
|
// (if it exists)
|
||||||
|
removeMatchingAssignmentFromQueue(matchingAssignment);
|
||||||
// remove the matching assignment from the assignment queue so we don't take the next check in
|
} else {
|
||||||
// (if it exists)
|
assignmentUUID = QUuid();
|
||||||
removeMatchingAssignmentFromQueue(matchingAssignment);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new session UUID for this node
|
// create a new session UUID for this node
|
||||||
nodeUUID = QUuid::createUuid();
|
QUuid nodeUUID = QUuid::createUuid();
|
||||||
|
|
||||||
SharedNodePointer newNode = NodeList::getInstance()->addOrUpdateNode(nodeUUID, nodeType, publicSockAddr, localSockAddr);
|
SharedNodePointer newNode = NodeList::getInstance()->addOrUpdateNode(nodeUUID, nodeType, publicSockAddr, localSockAddr);
|
||||||
|
|
||||||
|
// when the newNode is created the linked data is also created, if this was a static assignment set the UUID
|
||||||
|
reinterpret_cast<DomainServerNodeData*>(newNode->getLinkedData())->setStaticAssignmentUUID(assignmentUUID);
|
||||||
|
|
||||||
if (!authJsonObject.isEmpty()) {
|
if (!authJsonObject.isEmpty()) {
|
||||||
// pull the connection secret from the authJsonObject and set it as the connection secret for this node
|
// pull the connection secret from the authJsonObject and set it as the connection secret for this node
|
||||||
QUuid connectionSecret(authJsonObject["data"].toObject()["connection_secret"].toString());
|
QUuid connectionSecret(authJsonObject["data"].toObject()["connection_secret"].toString());
|
||||||
|
@ -779,19 +782,24 @@ void DomainServer::nodeAdded(SharedNodePointer node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DomainServer::nodeKilled(SharedNodePointer node) {
|
void DomainServer::nodeKilled(SharedNodePointer node) {
|
||||||
// if this node's UUID matches a static assignment we need to throw it back in the assignment queue
|
|
||||||
SharedAssignmentPointer matchedAssignment = _staticAssignmentHash.value(node->getUUID());
|
|
||||||
|
|
||||||
if (matchedAssignment) {
|
|
||||||
refreshStaticAssignmentAndAddToQueue(matchedAssignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleanup the connection secrets that we set up for this node (on the other nodes)
|
|
||||||
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
|
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
|
||||||
foreach (const QUuid& otherNodeSessionUUID, nodeData->getSessionSecretHash().keys()) {
|
if (nodeData) {
|
||||||
SharedNodePointer otherNode = NodeList::getInstance()->nodeWithUUID(otherNodeSessionUUID);
|
// if this node's UUID matches a static assignment we need to throw it back in the assignment queue
|
||||||
if (otherNode) {
|
if (!nodeData->getStaticAssignmentUUID().isNull()) {
|
||||||
reinterpret_cast<DomainServerNodeData*>(otherNode->getLinkedData())->getSessionSecretHash().remove(node->getUUID());
|
SharedAssignmentPointer matchedAssignment = _staticAssignmentHash.value(nodeData->getStaticAssignmentUUID());
|
||||||
|
|
||||||
|
if (matchedAssignment) {
|
||||||
|
refreshStaticAssignmentAndAddToQueue(matchedAssignment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cleanup the connection secrets that we set up for this node (on the other nodes)
|
||||||
|
foreach (const QUuid& otherNodeSessionUUID, nodeData->getSessionSecretHash().keys()) {
|
||||||
|
SharedNodePointer otherNode = NodeList::getInstance()->nodeWithUUID(otherNodeSessionUUID);
|
||||||
|
if (otherNode) {
|
||||||
|
reinterpret_cast<DomainServerNodeData*>(otherNode->getLinkedData())->getSessionSecretHash().remove(node->getUUID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
domain-server/src/DomainServerNodeData.cpp
Normal file
16
domain-server/src/DomainServerNodeData.cpp
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
//
|
||||||
|
// DomainServerNodeData.cpp
|
||||||
|
// hifi
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 2/6/2014.
|
||||||
|
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "DomainServerNodeData.h"
|
||||||
|
|
||||||
|
DomainServerNodeData::DomainServerNodeData() :
|
||||||
|
_sessionSecretHash(),
|
||||||
|
_staticAssignmentUUID()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -10,17 +10,22 @@
|
||||||
#define __hifi__DomainServerNodeData__
|
#define __hifi__DomainServerNodeData__
|
||||||
|
|
||||||
#include <QtCore/QHash>
|
#include <QtCore/QHash>
|
||||||
|
#include <QtCore/QUuid>
|
||||||
|
|
||||||
#include <NodeData.h>
|
#include <NodeData.h>
|
||||||
|
|
||||||
class DomainServerNodeData : public NodeData {
|
class DomainServerNodeData : public NodeData {
|
||||||
public:
|
public:
|
||||||
DomainServerNodeData() : _sessionSecretHash() {};
|
DomainServerNodeData();
|
||||||
int parseData(const QByteArray& packet) { return 0; }
|
int parseData(const QByteArray& packet) { return 0; }
|
||||||
|
|
||||||
|
void setStaticAssignmentUUID(const QUuid& staticAssignmentUUID) { _staticAssignmentUUID = staticAssignmentUUID; }
|
||||||
|
const QUuid& getStaticAssignmentUUID() const { return _staticAssignmentUUID; }
|
||||||
|
|
||||||
QHash<QUuid, QUuid>& getSessionSecretHash() { return _sessionSecretHash; }
|
QHash<QUuid, QUuid>& getSessionSecretHash() { return _sessionSecretHash; }
|
||||||
private:
|
private:
|
||||||
QHash<QUuid, QUuid> _sessionSecretHash;
|
QHash<QUuid, QUuid> _sessionSecretHash;
|
||||||
|
QUuid _staticAssignmentUUID;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__DomainServerNodeData__) */
|
#endif /* defined(__hifi__DomainServerNodeData__) */
|
||||||
|
|
|
@ -41,6 +41,7 @@ public:
|
||||||
const JSONCallbackParameters& callbackParams = JSONCallbackParameters(),
|
const JSONCallbackParameters& callbackParams = JSONCallbackParameters(),
|
||||||
const QByteArray& dataByteArray = QByteArray());
|
const QByteArray& dataByteArray = QByteArray());
|
||||||
|
|
||||||
|
const QUrl& getRootURL() const { return _rootURL; }
|
||||||
void setRootURL(const QUrl& rootURL);
|
void setRootURL(const QUrl& rootURL);
|
||||||
bool hasAuthEndpoint() { return !_rootURL.isEmpty(); }
|
bool hasAuthEndpoint() { return !_rootURL.isEmpty(); }
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ void DomainInfo::reset() {
|
||||||
_hostname = QString();
|
_hostname = QString();
|
||||||
_sockAddr.setAddress(QHostAddress::Null);
|
_sockAddr.setAddress(QHostAddress::Null);
|
||||||
_assignmentUUID = QUuid();
|
_assignmentUUID = QUuid();
|
||||||
_connectionSecret = QString();
|
_connectionSecret = QUuid();
|
||||||
_registrationToken = QByteArray();
|
_registrationToken = QByteArray();
|
||||||
_rootAuthenticationURL = QUrl();
|
_rootAuthenticationURL = QUrl();
|
||||||
_publicKey = QString();
|
_publicKey = QString();
|
||||||
|
|
|
@ -24,6 +24,8 @@ class DomainInfo : public QObject {
|
||||||
public:
|
public:
|
||||||
DomainInfo();
|
DomainInfo();
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
void parseAuthInformationFromJsonObject(const QJsonObject& jsonObject);
|
void parseAuthInformationFromJsonObject(const QJsonObject& jsonObject);
|
||||||
|
|
||||||
const QUuid& getUUID() const { return _uuid; }
|
const QUuid& getUUID() const { return _uuid; }
|
||||||
|
@ -62,8 +64,6 @@ signals:
|
||||||
void hostnameChanged(const QString& hostname);
|
void hostnameChanged(const QString& hostname);
|
||||||
void connectedToDomain(const QString& hostname);
|
void connectedToDomain(const QString& hostname);
|
||||||
private:
|
private:
|
||||||
void reset();
|
|
||||||
|
|
||||||
QUuid _uuid;
|
QUuid _uuid;
|
||||||
QString _hostname;
|
QString _hostname;
|
||||||
HifiSockAddr _sockAddr;
|
HifiSockAddr _sockAddr;
|
||||||
|
|
Loading…
Reference in a new issue