Merge branch 'master' of github.com:highfidelity/hifi into no-id-swap-redux

This commit is contained in:
Seth Alves 2015-05-21 09:20:56 -07:00
commit 52ce26d80d
19 changed files with 897 additions and 775 deletions

View file

@ -43,8 +43,7 @@ int hifiSockAddrMeta = qRegisterMetaType<HifiSockAddr>("HifiSockAddr");
AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QString assignmentPool, AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QString assignmentPool,
QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort, QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort,
quint16 assignmentMonitorPort) : quint16 assignmentMonitorPort) :
_assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME), _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME)
_localASPortSharedMem(NULL)
{ {
LogUtils::init(); LogUtils::init();
@ -181,8 +180,7 @@ void AssignmentClient::sendAssignmentRequest() {
if (_assignmentServerHostname == "localhost") { if (_assignmentServerHostname == "localhost") {
// we want to check again for the local domain-server port in case the DS has restarted // we want to check again for the local domain-server port in case the DS has restarted
quint16 localAssignmentServerPort; quint16 localAssignmentServerPort;
if (nodeList->getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, _localASPortSharedMem, if (nodeList->getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, localAssignmentServerPort)) {
localAssignmentServerPort)) {
if (localAssignmentServerPort != _assignmentServerSocket.getPort()) { if (localAssignmentServerPort != _assignmentServerSocket.getPort()) {
qDebug() << "Port for local assignment server read from shared memory is" qDebug() << "Port for local assignment server read from shared memory is"
<< localAssignmentServerPort; << localAssignmentServerPort;
@ -190,7 +188,11 @@ void AssignmentClient::sendAssignmentRequest() {
_assignmentServerSocket.setPort(localAssignmentServerPort); _assignmentServerSocket.setPort(localAssignmentServerPort);
nodeList->setAssignmentServerSocket(_assignmentServerSocket); nodeList->setAssignmentServerSocket(_assignmentServerSocket);
} }
} else {
qDebug() << "Failed to read local assignment server port from shared memory"
<< "- will send assignment request to previous assignment server socket.";
} }
} }
nodeList->sendAssignment(_requestAssignment); nodeList->sendAssignment(_requestAssignment);

View file

@ -44,7 +44,6 @@ private:
QPointer<ThreadedAssignment> _currentAssignment; QPointer<ThreadedAssignment> _currentAssignment;
QString _assignmentServerHostname; QString _assignmentServerHostname;
HifiSockAddr _assignmentServerSocket; HifiSockAddr _assignmentServerSocket;
QSharedMemory* _localASPortSharedMem; // memory shared with domain server
QTimer _requestTimer; // timer for requesting and assignment QTimer _requestTimer; // timer for requesting and assignment
QTimer _statsTimerACM; // timer for sending stats to assignment client monitor QTimer _statsTimerACM; // timer for sending stats to assignment client monitor

View file

@ -1,4 +1,6 @@
[ {
"version": 1.0,
"settings": [
{ {
"name": "metaverse", "name": "metaverse",
"label": "Metaverse / Networking", "label": "Metaverse / Networking",
@ -85,11 +87,18 @@
"help": "Password used for basic HTTP authentication. Leave this blank if you do not want to change it.", "help": "Password used for basic HTTP authentication. Leave this blank if you do not want to change it.",
"value-hidden": true "value-hidden": true
}, },
{
"name": "restricted_access",
"type": "checkbox",
"label": "Restricted Access",
"default": false,
"help": "Only users listed in \"Allowed Users\" can enter your domain."
},
{ {
"name": "allowed_users", "name": "allowed_users",
"type": "table", "type": "table",
"label": "Allowed Users", "label": "Allowed Users",
"help": "List the High Fidelity names for people you want to be able to connect to this domain.<br/>An empty list means everyone.<br/>You can always connect from the domain-server machine.", "help": "You can always connect from the domain-server machine.",
"numbered": false, "numbered": false,
"columns": [ "columns": [
{ {
@ -124,8 +133,8 @@
{ {
"name": "editors_are_rezzers", "name": "editors_are_rezzers",
"type": "checkbox", "type": "checkbox",
"label": "Only editors can create new entities", "label": "Only Editors Can Create Entities",
"help": "When checked, only those who can edit the domain can create new entites.", "help": "Only users listed in \"Allowed Editors\" can create new entites.",
"default": false "default": false
} }
] ]
@ -180,8 +189,9 @@
}, },
{ {
"name": "enable_filter", "name": "enable_filter",
"label": "Low-pass Filter",
"type": "checkbox", "type": "checkbox",
"help": "positional audio stream uses lowpass filter", "help": "Positional audio stream uses low-pass filter",
"default": true "default": true
}, },
{ {
@ -282,7 +292,7 @@
"name": "dynamic_jitter_buffer", "name": "dynamic_jitter_buffer",
"type": "checkbox", "type": "checkbox",
"label": "Dynamic Jitter Buffers", "label": "Dynamic Jitter Buffers",
"help": "dynamically buffer client audio based on perceived jitter in packet receipt timing", "help": "Dynamically buffer client audio based on perceived jitter in packet receipt timing",
"default": false, "default": false,
"advanced": true "advanced": true
}, },
@ -305,8 +315,8 @@
{ {
"name": "use_stdev_for_desired_calc", "name": "use_stdev_for_desired_calc",
"type": "checkbox", "type": "checkbox",
"label": "Use Stdev for Desired Jitter Frames Calc:", "label": "Stdev for Desired Jitter Frames Calc",
"help": "use Philip's method (stdev of timegaps) to calculate desired jitter frames (otherwise Fred's max timegap method is used)", "help": "Use Philip's method (stdev of timegaps) to calculate desired jitter frames (otherwise Fred's max timegap method is used)",
"default": false, "default": false,
"advanced": true "advanced": true
}, },
@ -320,7 +330,7 @@
}, },
{ {
"name": "window_seconds_for_desired_calc_on_too_many_starves", "name": "window_seconds_for_desired_calc_on_too_many_starves",
"label": "Timegaps Window (A) Seconds:", "label": "Timegaps Window (A) Seconds",
"help": "Window A contains a history of timegaps. Its max timegap is used to re-evaluate the desired jitter frames when too many starves occur within it.", "help": "Window A contains a history of timegaps. Its max timegap is used to re-evaluate the desired jitter frames when too many starves occur within it.",
"placeholder": "50", "placeholder": "50",
"default": "50", "default": "50",
@ -328,7 +338,7 @@
}, },
{ {
"name": "window_seconds_for_desired_reduction", "name": "window_seconds_for_desired_reduction",
"label": "Timegaps Window (B) Seconds:", "label": "Timegaps Window (B) Seconds",
"help": "Window B contains a history of timegaps. Its max timegap is used as a ceiling for the desired jitter frames value.", "help": "Window B contains a history of timegaps. Its max timegap is used as a ceiling for the desired jitter frames value.",
"placeholder": "10", "placeholder": "10",
"default": "10", "default": "10",
@ -337,16 +347,16 @@
{ {
"name": "repetition_with_fade", "name": "repetition_with_fade",
"type": "checkbox", "type": "checkbox",
"label": "Repetition with Fade:", "label": "Repetition with Fade",
"help": "dropped frames and mixing during starves repeat the last frame, eventually fading to silence", "help": "Dropped frames and mixing during starves repeat the last frame, eventually fading to silence",
"default": false, "default": false,
"advanced": true "advanced": true
}, },
{ {
"name": "print_stream_stats", "name": "print_stream_stats",
"type": "checkbox", "type": "checkbox",
"label": "Print Stream Stats:", "label": "Print Stream Stats",
"help": "audio upstream and downstream stats of each agent printed to audio-mixer stdout", "help": "Audio upstream and downstream stats of each agent printed to audio-mixer stdout",
"default": false, "default": false,
"advanced": true "advanced": true
} }
@ -440,6 +450,7 @@
{ {
"name": "NoPersist", "name": "NoPersist",
"type": "checkbox", "type": "checkbox",
"label": "Disable Persistence",
"help": "Don't persist your entities to a file.", "help": "Don't persist your entities to a file.",
"default": false, "default": false,
"advanced": true "advanced": true
@ -447,6 +458,7 @@
{ {
"name": "NoBackup", "name": "NoBackup",
"type": "checkbox", "type": "checkbox",
"label": "Disable Backup",
"help": "Don't regularly backup your persisted entities to a backup file.", "help": "Don't regularly backup your persisted entities to a backup file.",
"default": false, "default": false,
"advanced": true "advanced": true
@ -454,7 +466,7 @@
{ {
"name": "statusHost", "name": "statusHost",
"label": "Status Hostname", "label": "Status Hostname",
"help": "host name or IP address of the server for accessing the status page", "help": "Host name or IP address of the server for accessing the status page",
"placeholder": "", "placeholder": "",
"default": "", "default": "",
"advanced": true "advanced": true
@ -462,7 +474,7 @@
{ {
"name": "statusPort", "name": "statusPort",
"label": "Status Port", "label": "Status Port",
"help": "port of the server for accessing the status page", "help": "Port of the server for accessing the status page",
"placeholder": "", "placeholder": "",
"default": "", "default": "",
"advanced": true "advanced": true
@ -470,6 +482,7 @@
{ {
"name": "wantEditLogging", "name": "wantEditLogging",
"type": "checkbox", "type": "checkbox",
"label": "Edit Logging",
"help": "Logging of all edits to entities", "help": "Logging of all edits to entities",
"default": true, "default": true,
"advanced": true "advanced": true
@ -477,28 +490,32 @@
{ {
"name": "verboseDebug", "name": "verboseDebug",
"type": "checkbox", "type": "checkbox",
"help": "lots of debugging", "label": "Verbose Debug",
"help": "Lots of debugging",
"default": false, "default": false,
"advanced": true "advanced": true
}, },
{ {
"name": "debugReceiving", "name": "debugReceiving",
"type": "checkbox", "type": "checkbox",
"help": "extra debugging on receiving", "label": "Extra Receiving Debug",
"help": "Extra debugging on receiving",
"default": false, "default": false,
"advanced": true "advanced": true
}, },
{ {
"name": "debugSending", "name": "debugSending",
"type": "checkbox", "type": "checkbox",
"help": "extra debugging on sending", "label": "Extra Sending Debug",
"help": "Extra debugging on sending",
"default": false, "default": false,
"advanced": true "advanced": true
}, },
{ {
"name": "debugTimestampNow", "name": "debugTimestampNow",
"type": "checkbox", "type": "checkbox",
"help": "extra debugging for usecTimestampNow() function", "label": "Extra Timestamp Debugging",
"help": "Extra debugging for usecTimestampNow() function",
"default": false, "default": false,
"advanced": true "advanced": true
}, },
@ -529,3 +546,4 @@
] ]
} }
] ]
}

File diff suppressed because one or more lines are too long

View file

@ -109,6 +109,13 @@ table {
width: 100%; width: 100%;
} }
/* styling for bootstrap-switch toggles */
.checkbox-help {
margin-top: 10px;
}
/* CSS only spinner for AJAX requests */
.spinner { .spinner {
margin: 30px auto 0; margin: 30px auto 0;
width: 70px; width: 70px;

View file

@ -7,7 +7,9 @@
<link href="/css/bootstrap.min.css" rel="stylesheet" media="screen"> <link href="/css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="/css/style.css" rel="stylesheet" media="screen"> <link href="/css/style.css" rel="stylesheet" media="screen">
<link href="/css/sweetalert.css" rel="stylesheet" media="screen"> <link href="/css/sweetalert.css" rel="stylesheet" media="screen">
<link href="/css/bootstrap-switch.min.css" rel="stylesheet" media="screen">
<link href="/stats/css/json.human.css" rel="stylesheet" media="screen"> <link href="/stats/css/json.human.css" rel="stylesheet" media="screen">
</head> </head>
<body> <body>
<nav class="navbar navbar-default" role="navigation"> <nav class="navbar navbar-default" role="navigation">

View file

@ -99,7 +99,8 @@
<script src='/js/underscore-min.js'></script> <script src='/js/underscore-min.js'></script>
<script src='/js/underscore-keypath.min.js'></script> <script src='/js/underscore-keypath.min.js'></script>
<script src='/js/bootbox.min.js'></script> <script src='/js/bootbox.min.js'></script>
<script src='/js/sweetalert.min.js'></script> <script src='js/bootstrap-switch.min.js'></script>
<script src='/js/settings.js'></script> <script src='js/sweetalert.min.js'></script>
<script src='/js/form2js.min.js'></script> <script src='js/settings.js'></script>
<script src='js/form2js.min.js'></script>
<!--#include virtual="page-end.html"--> <!--#include virtual="page-end.html"-->

File diff suppressed because one or more lines are too long

View file

@ -60,10 +60,15 @@ var viewHelpers = {
if (setting.label) { if (setting.label) {
form_group += "<label class='" + label_class + "'>" + setting.label + "</label>" form_group += "<label class='" + label_class + "'>" + setting.label + "</label>"
} }
form_group += "<div class='checkbox" + (isLocked ? " disabled" : "") + "'>"
form_group += "<label for='" + keypath + "'>" form_group += "<div class='toggle-checkbox-container" + (isLocked ? " disabled" : "") + "'>"
form_group += "<input type='checkbox'" + common_attrs() + (setting_value ? "checked" : "") + (isLocked ? " disabled" : "") + "/>" form_group += "<input type='checkbox'" + common_attrs('toggle-checkbox') + (setting_value ? "checked" : "")
form_group += " " + setting.help + "</label>"; form_group += (isLocked ? " disabled" : "") + "/>"
if (setting.help) {
form_group += "<span class='help-block checkbox-help'>" + setting.help + "</span>";
}
form_group += "</div>" form_group += "</div>"
} else { } else {
input_type = _.has(setting, 'type') ? setting.type : "text" input_type = _.has(setting, 'type') ? setting.type : "text"
@ -201,10 +206,17 @@ $(document).ready(function(){
$('#' + Settings.FORM_ID).on('change', '.' + Settings.TRIGGER_CHANGE_CLASS , function(){ $('#' + Settings.FORM_ID).on('change', '.' + Settings.TRIGGER_CHANGE_CLASS , function(){
// this input was changed, add the changed data attribute to it // this input was changed, add the changed data attribute to it
$(this).attr('data-changed', true) $(this).attr('data-changed', true);
badgeSidebarForDifferences($(this)) badgeSidebarForDifferences($(this));
}) });
$('#' + Settings.FORM_ID).on('switchChange.bootstrapSwitch', 'input.toggle-checkbox', function(){
// this checkbox was changed, add the changed data attribute to it
$(this).attr('data-changed', true);
badgeSidebarForDifferences($(this));
});
$('.advanced-toggle').click(function(){ $('.advanced-toggle').click(function(){
Settings.showAdvanced = !Settings.showAdvanced Settings.showAdvanced = !Settings.showAdvanced
@ -735,6 +747,9 @@ function reloadSettings() {
// call our method to setup the place names table // call our method to setup the place names table
setupPlacesTable(); setupPlacesTable();
// setup any bootstrap switches
$('.toggle-checkbox').bootstrapSwitch();
// add tooltip to locked settings // add tooltip to locked settings
$('label.locked').tooltip({ $('label.locked').tooltip({
placement: 'right', placement: 'right',

View file

@ -44,13 +44,10 @@ int const DomainServer::EXIT_CODE_REBOOT = 234923;
const QString ICE_SERVER_DEFAULT_HOSTNAME = "ice.highfidelity.io"; const QString ICE_SERVER_DEFAULT_HOSTNAME = "ice.highfidelity.io";
const QString ALLOWED_USERS_SETTINGS_KEYPATH = "security.allowed_users";
const QString MAXIMUM_USER_CAPACITY = "security.maximum_user_capacity"; const QString MAXIMUM_USER_CAPACITY = "security.maximum_user_capacity";
const QString ALLOWED_EDITORS_SETTINGS_KEYPATH = "security.allowed_editors"; const QString ALLOWED_EDITORS_SETTINGS_KEYPATH = "security.allowed_editors";
const QString EDITORS_ARE_REZZERS_KEYPATH = "security.editors_are_rezzers"; const QString EDITORS_ARE_REZZERS_KEYPATH = "security.editors_are_rezzers";
DomainServer::DomainServer(int argc, char* argv[]) : DomainServer::DomainServer(int argc, char* argv[]) :
QCoreApplication(argc, argv), QCoreApplication(argc, argv),
_httpManager(DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this), _httpManager(DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this),
@ -776,9 +773,8 @@ bool DomainServer::shouldAllowConnectionFromNode(const QString& username,
const HifiSockAddr& senderSockAddr, const HifiSockAddr& senderSockAddr,
QString& reasonReturn) { QString& reasonReturn) {
const QVariant* allowedUsersVariant = valueForKeyPath(_settingsManager.getSettingsMap(), bool isRestrictingAccess =
ALLOWED_USERS_SETTINGS_KEYPATH); _settingsManager.valueOrDefaultValueForKeyPath(RESTRICTED_ACCESS_SETTINGS_KEYPATH).toBool();
QStringList allowedUsers = allowedUsersVariant ? allowedUsersVariant->toStringList() : QStringList();
// we always let in a user who is sending a packet from our local socket or from the localhost address // we always let in a user who is sending a packet from our local socket or from the localhost address
if (senderSockAddr.getAddress() == DependencyManager::get<LimitedNodeList>()->getLocalSockAddr().getAddress() if (senderSockAddr.getAddress() == DependencyManager::get<LimitedNodeList>()->getLocalSockAddr().getAddress()
@ -786,18 +782,24 @@ bool DomainServer::shouldAllowConnectionFromNode(const QString& username,
return true; return true;
} }
if (allowedUsers.count() > 0) { if (isRestrictingAccess) {
QStringList allowedUsers =
_settingsManager.valueOrDefaultValueForKeyPath(ALLOWED_USERS_SETTINGS_KEYPATH).toStringList();
if (allowedUsers.contains(username, Qt::CaseInsensitive)) { if (allowedUsers.contains(username, Qt::CaseInsensitive)) {
if (verifyUsersKey(username, usernameSignature, reasonReturn)) { if (!verifyUsersKey(username, usernameSignature, reasonReturn)) {
return true; return false;
} }
} else { } else {
qDebug() << "Connect request denied for user" << username << "not in allowed users list."; qDebug() << "Connect request denied for user" << username << "not in allowed users list.";
reasonReturn = "User not on whitelist."; reasonReturn = "User not on whitelist.";
}
return false; return false;
} else { }
// we have no allowed user list. }
// either we aren't restricting users, or this user is in the allowed list
// if this user is in the editors list, exempt them from the max-capacity check // if this user is in the editors list, exempt them from the max-capacity check
const QVariant* allowedEditorsVariant = const QVariant* allowedEditorsVariant =
@ -825,7 +827,6 @@ bool DomainServer::shouldAllowConnectionFromNode(const QString& username,
return true; return true;
} }
}
void DomainServer::preloadAllowedUserPublicKeys() { void DomainServer::preloadAllowedUserPublicKeys() {
const QVariant* allowedUsersVariant = valueForKeyPath(_settingsManager.getSettingsMap(), ALLOWED_USERS_SETTINGS_KEYPATH); const QVariant* allowedUsersVariant = valueForKeyPath(_settingsManager.getSettingsMap(), ALLOWED_USERS_SETTINGS_KEYPATH);
@ -1255,10 +1256,8 @@ void DomainServer::sendHeartbeatToDataServer(const QString& networkAddress) {
// add a flag to indicate if this domain uses restricted access - for now that will exclude it from listings // add a flag to indicate if this domain uses restricted access - for now that will exclude it from listings
const QString RESTRICTED_ACCESS_FLAG = "restricted"; const QString RESTRICTED_ACCESS_FLAG = "restricted";
const QVariant* allowedUsersVariant = valueForKeyPath(_settingsManager.getSettingsMap(), domainObject[RESTRICTED_ACCESS_FLAG] =
ALLOWED_USERS_SETTINGS_KEYPATH); _settingsManager.valueOrDefaultValueForKeyPath(RESTRICTED_ACCESS_SETTINGS_KEYPATH).toBool();
QStringList allowedUsers = allowedUsersVariant ? allowedUsersVariant->toStringList() : QStringList();
domainObject[RESTRICTED_ACCESS_FLAG] = (allowedUsers.size() > 0);
// add the number of currently connected agent users // add the number of currently connected agent users
int numConnectedAuthedUsers = 0; int numConnectedAuthedUsers = 0;

View file

@ -14,6 +14,7 @@
#include <QtCore/QFile> #include <QtCore/QFile>
#include <QtCore/QJsonArray> #include <QtCore/QJsonArray>
#include <QtCore/QJsonObject> #include <QtCore/QJsonObject>
#include <QtCore/QSettings>
#include <QtCore/QStandardPaths> #include <QtCore/QStandardPaths>
#include <QtCore/QUrl> #include <QtCore/QUrl>
#include <QtCore/QUrlQuery> #include <QtCore/QUrlQuery>
@ -42,34 +43,74 @@ DomainServerSettingsManager::DomainServerSettingsManager() :
QFile descriptionFile(QCoreApplication::applicationDirPath() + SETTINGS_DESCRIPTION_RELATIVE_PATH); QFile descriptionFile(QCoreApplication::applicationDirPath() + SETTINGS_DESCRIPTION_RELATIVE_PATH);
descriptionFile.open(QIODevice::ReadOnly); descriptionFile.open(QIODevice::ReadOnly);
_descriptionArray = QJsonDocument::fromJson(descriptionFile.readAll()).array(); QJsonDocument descriptionDocument = QJsonDocument::fromJson(descriptionFile.readAll());
if (descriptionDocument.isObject()) {
QJsonObject descriptionObject = descriptionDocument.object();
const QString DESCRIPTION_VERSION_KEY = "version";
if (descriptionObject.contains(DESCRIPTION_VERSION_KEY)) {
// read the version from the settings description
_descriptionVersion = descriptionObject[DESCRIPTION_VERSION_KEY].toDouble();
if (descriptionObject.contains(DESCRIPTION_SETTINGS_KEY)) {
_descriptionArray = descriptionDocument.object()[DESCRIPTION_SETTINGS_KEY].toArray();
return;
}
}
}
qCritical() << "Did not find settings decription in JSON at" << SETTINGS_DESCRIPTION_RELATIVE_PATH
<< "- Unable to continue. domain-server will quit.";
QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection);
} }
void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList) { void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList) {
_configMap.loadMasterAndUserConfig(argumentList); _configMap.loadMasterAndUserConfig(argumentList);
// for now we perform a temporary transition from http-username and http-password to http_username and http_password // What settings version were we before and what are we using now?
const QVariant* oldUsername = valueForKeyPath(_configMap.getUserConfig(), "security.http-username"); // Do we need to do any re-mapping?
const QVariant* oldPassword = valueForKeyPath(_configMap.getUserConfig(), "security.http-password"); QSettings appSettings;
const QString JSON_SETTINGS_VERSION_KEY = "json-settings/version";
double oldVersion = appSettings.value(JSON_SETTINGS_VERSION_KEY, 0.0).toDouble();
if (oldUsername || oldPassword) { if (oldVersion != _descriptionVersion) {
QVariantMap& settingsMap = *reinterpret_cast<QVariantMap*>(_configMap.getUserConfig()["security"].data()); qDebug() << "Previous domain-server settings version was"
<< QString::number(oldVersion, 'g', 8) << "and the new version is"
<< QString::number(_descriptionVersion, 'g', 8) << "- checking if any re-mapping is required";
// remove old keys, move to new format // we have a version mismatch - for now handle custom behaviour here since there are not many remappings
if (oldUsername) { if (oldVersion < 1.0) {
settingsMap["http_username"] = oldUsername->toString(); // This was prior to the introduction of security.restricted_access
settingsMap.remove("http-username"); // If the user has a list of allowed users then set their value for security.restricted_access to true
}
if (oldPassword) { QVariant* allowedUsers = valueForKeyPath(_configMap.getMergedConfig(), ALLOWED_USERS_SETTINGS_KEYPATH);
settingsMap["http_password"] = oldPassword->toString();
settingsMap.remove("http-password");
}
// save the updated settings if (allowedUsers
&& allowedUsers->canConvert(QMetaType::QVariantList)
&& reinterpret_cast<QVariantList*>(allowedUsers)->size() > 0) {
qDebug() << "Forcing security.restricted_access to TRUE since there was an"
<< "existing list of allowed users.";
// In the pre-toggle system the user had a list of allowed users, so
// we need to set security.restricted_access to true
QVariant* restrictedAccess = valueForKeyPath(_configMap.getUserConfig(),
RESTRICTED_ACCESS_SETTINGS_KEYPATH,
true);
*restrictedAccess = QVariant(true);
// write the new settings to the json file
persistToFile(); persistToFile();
} }
} }
}
// write the current description version to our settings
appSettings.setValue(JSON_SETTINGS_VERSION_KEY, _descriptionVersion);
}
QVariant DomainServerSettingsManager::valueOrDefaultValueForKeyPath(const QString &keyPath) { QVariant DomainServerSettingsManager::valueOrDefaultValueForKeyPath(const QString &keyPath) {
const QVariant* foundValue = valueForKeyPath(_configMap.getMergedConfig(), keyPath); const QVariant* foundValue = valueForKeyPath(_configMap.getMergedConfig(), keyPath);

View file

@ -23,6 +23,9 @@ const QString SETTINGS_PATHS_KEY = "paths";
const QString SETTINGS_PATH = "/settings"; const QString SETTINGS_PATH = "/settings";
const QString SETTINGS_PATH_JSON = SETTINGS_PATH + ".json"; const QString SETTINGS_PATH_JSON = SETTINGS_PATH + ".json";
const QString ALLOWED_USERS_SETTINGS_KEYPATH = "security.allowed_users";
const QString RESTRICTED_ACCESS_SETTINGS_KEYPATH = "security.restricted_access";
class DomainServerSettingsManager : public QObject { class DomainServerSettingsManager : public QObject {
Q_OBJECT Q_OBJECT
public: public:
@ -44,6 +47,7 @@ private:
QJsonObject settingDescriptionFromGroup(const QJsonObject& groupObject, const QString& settingName); QJsonObject settingDescriptionFromGroup(const QJsonObject& groupObject, const QString& settingName);
void persistToFile(); void persistToFile();
double _descriptionVersion;
QJsonArray _descriptionArray; QJsonArray _descriptionArray;
HifiConfigVariantMap _configMap; HifiConfigVariantMap _configMap;
}; };

View file

@ -762,22 +762,15 @@ void LimitedNodeList::putLocalPortIntoSharedMemory(const QString key, QObject* p
} }
bool LimitedNodeList::getLocalServerPortFromSharedMemory(const QString key, QSharedMemory*& sharedMem, bool LimitedNodeList::getLocalServerPortFromSharedMemory(const QString key, quint16& localPort) {
quint16& localPort) { QSharedMemory sharedMem(key);
if (!sharedMem) { if (!sharedMem.attach(QSharedMemory::ReadOnly)) {
sharedMem = new QSharedMemory(key, this);
if (!sharedMem->attach(QSharedMemory::ReadOnly)) {
qWarning() << "Could not attach to shared memory at key" << key; qWarning() << "Could not attach to shared memory at key" << key;
} return false;
} } else {
sharedMem.lock();
if (sharedMem->isAttached()) { memcpy(&localPort, sharedMem.data(), sizeof(localPort));
sharedMem->lock(); sharedMem.unlock();
memcpy(&localPort, sharedMem->data(), sizeof(localPort));
sharedMem->unlock();
return true; return true;
} }
return false;
} }

View file

@ -200,7 +200,7 @@ public:
} }
void putLocalPortIntoSharedMemory(const QString key, QObject* parent, quint16 localPort); void putLocalPortIntoSharedMemory(const QString key, QObject* parent, quint16 localPort);
bool getLocalServerPortFromSharedMemory(const QString key, QSharedMemory*& sharedMem, quint16& localPort); bool getLocalServerPortFromSharedMemory(const QString key, quint16& localPort);
public slots: public slots:
void reset(); void reset();

View file

@ -335,12 +335,8 @@ void NodeList::sendDomainServerCheckIn() {
if (_domainHandler.getSockAddr().getAddress() == QHostAddress::LocalHost if (_domainHandler.getSockAddr().getAddress() == QHostAddress::LocalHost
|| _domainHandler.getHostname() == "localhost") { || _domainHandler.getHostname() == "localhost") {
static QSharedMemory* localDSPortSharedMem = NULL;
quint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT; quint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT;
getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, domainPort);
localDSPortSharedMem,
domainPort);
qCDebug(networking) << "Local domain-server port read from shared memory (or default) is" << domainPort; qCDebug(networking) << "Local domain-server port read from shared memory (or default) is" << domainPort;
_domainHandler.setPort(domainPort); _domainHandler.setPort(domainPort);
} }

View file

@ -159,16 +159,17 @@ void HifiConfigVariantMap::addMissingValuesToExistingMap(QVariantMap& existingMa
} }
} }
QVariant* valueForKeyPath(QVariantMap& variantMap, const QString& keyPath) { QVariant* valueForKeyPath(QVariantMap& variantMap, const QString& keyPath, bool shouldCreateIfMissing) {
int dotIndex = keyPath.indexOf('.'); int dotIndex = keyPath.indexOf('.');
QString firstKey = (dotIndex == -1) ? keyPath : keyPath.mid(0, dotIndex); QString firstKey = (dotIndex == -1) ? keyPath : keyPath.mid(0, dotIndex);
if (variantMap.contains(firstKey)) { if (shouldCreateIfMissing || variantMap.contains(firstKey)) {
if (dotIndex == -1) { if (dotIndex == -1) {
return &variantMap[firstKey]; return &variantMap[firstKey];
} else if (variantMap[firstKey].canConvert(QMetaType::QVariantMap)) { } else if (variantMap[firstKey].canConvert(QMetaType::QVariantMap)) {
return valueForKeyPath(*static_cast<QVariantMap*>(variantMap[firstKey].data()), keyPath.mid(dotIndex + 1)); return valueForKeyPath(*static_cast<QVariantMap*>(variantMap[firstKey].data()), keyPath.mid(dotIndex + 1),
shouldCreateIfMissing);
} }
} }

View file

@ -37,6 +37,6 @@ private:
void addMissingValuesToExistingMap(QVariantMap& existingMap, const QVariantMap& newMap); void addMissingValuesToExistingMap(QVariantMap& existingMap, const QVariantMap& newMap);
}; };
QVariant* valueForKeyPath(QVariantMap& variantMap, const QString& keyPath); QVariant* valueForKeyPath(QVariantMap& variantMap, const QString& keyPath, bool shouldCreateIfMissing = false);
#endif // hifi_HifiConfigVariantMap_h #endif // hifi_HifiConfigVariantMap_h