diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json
index bf238e657f..aca288c452 100644
--- a/domain-server/resources/describe-settings.json
+++ b/domain-server/resources/describe-settings.json
@@ -526,7 +526,7 @@
"groups": [
{
"label": "Group",
- "span": 4
+ "span": 5
},
{
"label": "Permissions ?",
@@ -540,8 +540,12 @@
"label": "Group Name"
},
{
- "name": "rank",
- "label": "Rank"
+ "name": "rank_id",
+ "label": "Rank ID"
+ },
+ {
+ "name": "rank_order",
+ "label": "Rank Order"
},
{
"name": "rank_name",
@@ -605,7 +609,7 @@
"groups": [
{
"label": "Group",
- "span": 4
+ "span": 5
},
{
"label": "Permissions ?",
@@ -619,8 +623,12 @@
"label": "Group Name"
},
{
- "name": "rank",
- "label": "Rank"
+ "name": "rank_id",
+ "label": "Rank ID"
+ },
+ {
+ "name": "rank_order",
+ "label": "Rank Order"
},
{
"name": "rank_name",
diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp
index 32c0eb00c9..08fe40faff 100644
--- a/domain-server/src/DomainGatekeeper.cpp
+++ b/domain-server/src/DomainGatekeeper.cpp
@@ -150,10 +150,12 @@ NodePermissions DomainGatekeeper::applyPermissionsForUser(bool isLocalUser,
// if this user is a known member of a group, give them the implied permissions
foreach (QUuid groupID, _server->_settingsManager.getGroupIDs()) {
- int rank = _server->_settingsManager.isGroupMember(verifiedUsername, groupID);
- if (rank >= 0) {
- userPerms |= _server->_settingsManager.getPermissionsForGroup(groupID, rank);
- qDebug() << "user-permissions: user is in group:" << groupID << " rank:" << rank << "so:" << userPerms;
+ QUuid rankID = _server->_settingsManager.isGroupMember(verifiedUsername, groupID);
+ if (rankID != QUuid()) {
+ userPerms |= _server->_settingsManager.getPermissionsForGroup(groupID, rankID);
+
+ GroupRank rank = _server->_settingsManager.getGroupRank(groupID, rankID);
+ qDebug() << "user-permissions: user is in group:" << groupID << " rank:" << rank.name << "so:" << userPerms;
}
}
@@ -161,12 +163,14 @@ NodePermissions DomainGatekeeper::applyPermissionsForUser(bool isLocalUser,
qDebug() << "------------------ checking blacklists ----------------------";
qDebug() << _server->_settingsManager.getBlacklistGroupIDs();
foreach (QUuid groupID, _server->_settingsManager.getBlacklistGroupIDs()) {
- if (_server->_settingsManager.isGroupMember(verifiedUsername, groupID)) {
- int rank = _server->_settingsManager.isGroupMember(verifiedUsername, groupID);
- qDebug() << groupID << verifiedUsername << "is member with rank" << rank;
- if (rank >= 0) {
- userPerms &= ~_server->_settingsManager.getForbiddensForGroup(groupID, rank);
- qDebug() << "user-permissions: user is in blacklist group:" << groupID << " rank:" << rank
+ QUuid rankID = _server->_settingsManager.isGroupMember(verifiedUsername, groupID);
+ if (rankID != QUuid()) {
+ QUuid rankID = _server->_settingsManager.isGroupMember(verifiedUsername, groupID);
+ if (rankID != QUuid()) {
+ userPerms &= ~_server->_settingsManager.getForbiddensForGroup(groupID, rankID);
+
+ GroupRank rank = _server->_settingsManager.getGroupRank(groupID, rankID);
+ qDebug() << "user-permissions: user is in blacklist group:" << groupID << " rank:" << rank.name
<< "so:" << userPerms;
}
} else {
@@ -197,6 +201,7 @@ void DomainGatekeeper::updateNodePermissions() {
if (node->getPermissions().isAssignment) {
// this node is an assignment-client
userPerms.isAssignment = true;
+ userPerms.permissions |= NodePermissions::Permission::canConnectToDomain;
userPerms.permissions |= NodePermissions::Permission::canAdjustLocks;
userPerms.permissions |= NodePermissions::Permission::canRezPermanentEntities;
userPerms.permissions |= NodePermissions::Permission::canRezTemporaryEntities;
@@ -263,9 +268,10 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo
// cleanup the PendingAssignedNodeData for this assignment now that it's connecting
_pendingAssignedNodes.erase(it);
- // always allow assignment clients to create and destroy entities
NodePermissions userPerms;
userPerms.isAssignment = true;
+ userPerms.permissions |= NodePermissions::Permission::canConnectToDomain;
+ // always allow assignment clients to create and destroy entities
userPerms.permissions |= NodePermissions::Permission::canAdjustLocks;
userPerms.permissions |= NodePermissions::Permission::canRezPermanentEntities;
userPerms.permissions |= NodePermissions::Permission::canRezTemporaryEntities;
@@ -701,33 +707,63 @@ void DomainGatekeeper::processICEPingReplyPacket(QSharedPointer
}
}
+// void DomainGatekeeper::getGroupMemberships(const QString& username) {
+// // loop through the groups mentioned on the settings page and ask if this user is in each. The replies
+// // will be received asynchronously and permissions will be updated as the answers come in.
+// QList groupIDs = _server->_settingsManager.getGroupIDs() + _server->_settingsManager.getBlacklistGroupIDs();
+// // TODO -- use alternative that allows checking entire group list in one call
+// foreach (QUuid groupID, groupIDs) {
+// if (groupID.isNull()) {
+// continue;
+// }
+// getIsGroupMember(username, groupID);
+// }
+// }
+
+// void DomainGatekeeper::getIsGroupMember(const QString& username, const QUuid groupID) {
+// JSONCallbackParameters callbackParams;
+// callbackParams.jsonCallbackReceiver = this;
+// callbackParams.jsonCallbackMethod = "getIsGroupMemberJSONCallback";
+// callbackParams.errorCallbackReceiver = this;
+// callbackParams.errorCallbackMethod = "getIsGroupMemberErrorCallback";
+
+// const QString GET_IS_GROUP_MEMBER_PATH = "api/v1/groups/%1/members/%2";
+// QString groupIDStr = groupID.toString().mid(1,36);
+// DependencyManager::get()->sendRequest(GET_IS_GROUP_MEMBER_PATH.arg(groupIDStr).arg(username),
+// AccountManagerAuth::Required,
+// QNetworkAccessManager::GetOperation, callbackParams);
+// }
+
+
+
void DomainGatekeeper::getGroupMemberships(const QString& username) {
// loop through the groups mentioned on the settings page and ask if this user is in each. The replies
// will be received asynchronously and permissions will be updated as the answers come in.
- QList groupIDs = _server->_settingsManager.getGroupIDs() + _server->_settingsManager.getBlacklistGroupIDs();
- // TODO -- use alternative that allows checking entire group list in one call
- foreach (QUuid groupID, groupIDs) {
- if (groupID.isNull()) {
- continue;
- }
- getIsGroupMember(username, groupID);
- }
-}
-void DomainGatekeeper::getIsGroupMember(const QString& username, const QUuid groupID) {
+ QJsonObject json;
+ QSet groupIDSet;
+ foreach (QUuid groupID, _server->_settingsManager.getGroupIDs() + _server->_settingsManager.getBlacklistGroupIDs()) {
+ groupIDSet += groupID.toString().mid(1,36);
+ }
+ QJsonArray groupIDs = QJsonArray::fromStringList(groupIDSet.toList());
+ json["groups"] = groupIDs;
+
JSONCallbackParameters callbackParams;
callbackParams.jsonCallbackReceiver = this;
callbackParams.jsonCallbackMethod = "getIsGroupMemberJSONCallback";
callbackParams.errorCallbackReceiver = this;
callbackParams.errorCallbackMethod = "getIsGroupMemberErrorCallback";
- const QString GET_IS_GROUP_MEMBER_PATH = "api/v1/groups/%1/members/%2";
- QString groupIDStr = groupID.toString().mid(1,36);
- DependencyManager::get()->sendRequest(GET_IS_GROUP_MEMBER_PATH.arg(groupIDStr).arg(username),
+ const QString GET_IS_GROUP_MEMBER_PATH = "api/v1/groups/members/%2";
+ DependencyManager::get()->sendRequest(GET_IS_GROUP_MEMBER_PATH.arg(username),
AccountManagerAuth::Required,
- QNetworkAccessManager::GetOperation, callbackParams);
+ QNetworkAccessManager::PostOperation, callbackParams,
+ QJsonDocument(json).toJson());
+
}
+
+
void DomainGatekeeper::getIsGroupMemberJSONCallback(QNetworkReply& requestReply) {
// {
// "data":{
@@ -746,8 +782,6 @@ void DomainGatekeeper::getIsGroupMemberJSONCallback(QNetworkReply& requestReply)
// }
-
-
QJsonObject jsonObject = QJsonDocument::fromJson(requestReply.readAll()).object();
qDebug() << "********* getIsGroupMember api call returned:" << QJsonDocument(jsonObject).toJson(QJsonDocument::Compact);
@@ -760,8 +794,9 @@ void DomainGatekeeper::getIsGroupMemberJSONCallback(QNetworkReply& requestReply)
_server->_settingsManager.clearGroupMemberships(username);
foreach (auto groupID, groups.keys()) {
QJsonObject group = groups[groupID].toObject();
- int order = group["order"].toInt();
- _server->_settingsManager.recordGroupMembership(username, groupID, order);
+ QJsonObject rank = group["rank"].toObject();
+ QUuid rankID = QUuid(rank["id"].toString());
+ _server->_settingsManager.recordGroupMembership(username, groupID, rankID);
}
} else {
qDebug() << "getIsGroupMember api call returned:" << QJsonDocument(jsonObject).toJson(QJsonDocument::Compact);
diff --git a/domain-server/src/DomainGatekeeper.h b/domain-server/src/DomainGatekeeper.h
index a5ff5d90a7..a18554338a 100644
--- a/domain-server/src/DomainGatekeeper.h
+++ b/domain-server/src/DomainGatekeeper.h
@@ -107,7 +107,7 @@ private:
NodePermissions applyPermissionsForUser(bool isLocalUser, NodePermissions userPerms, QString verifiedUsername);
void getGroupMemberships(const QString& username);
- void getIsGroupMember(const QString& username, const QUuid groupID);
+ // void getIsGroupMember(const QString& username, const QUuid groupID);
void getDomainOwnerFriendsList();
};
diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp
index 53b90551c1..bd429029ed 100644
--- a/domain-server/src/DomainServerSettingsManager.cpp
+++ b/domain-server/src/DomainServerSettingsManager.cpp
@@ -347,11 +347,31 @@ void DomainServerSettingsManager::packPermissionsForMap(QString mapName,
// convert details for each member of the subsection
QVariantList* permissionsList = reinterpret_cast(permissions);
(*permissionsList).clear();
- foreach (NodePermissionsKey userKey, agentPermissions.keys()) {
+ QList permissionsKeys = agentPermissions.keys();
+
+ // when a group is added from the domain-server settings page, the config map has a group-name with
+ // no ID or rank. We need to leave that there until we get a valid response back from the api.
+ // once we have the ranks and IDs, we need to delete the original entry so that it doesn't show
+ // up in the settings-page with undefined's after it.
+ QHash groupNamesWithRanks;
+ // note which groups have rank/ID information
+ foreach (NodePermissionsKey userKey, permissionsKeys) {
+ NodePermissionsPointer perms = agentPermissions[userKey];
+ if (perms->getRankID() != QUuid()) {
+ groupNamesWithRanks[userKey.first] = true;
+ }
+ }
+
+ // convert each group-name / rank-id pair to a variant-map
+ foreach (NodePermissionsKey userKey, permissionsKeys) {
NodePermissionsPointer perms = agentPermissions[userKey];
if (perms->isGroup()) {
- QVector rankNames = _groupRanks[perms->getGroupID()];
- *permissionsList += perms->toVariant(rankNames);
+ if (perms->getRankID() == QUuid() && groupNamesWithRanks.contains(userKey.first)) {
+ // skip over the entry that was created when the user added the group.
+ continue;
+ }
+ QHash& groupRanks = _groupRanks[perms->getGroupID()];
+ *permissionsList += perms->toVariant(groupRanks);
} else {
*permissionsList += perms->toVariant();
}
@@ -462,7 +482,7 @@ void DomainServerSettingsManager::unpackPermissions() {
}
if (perms->isGroup()) {
// the group-id was cached. hook-up the uuid in the uuid->group hash
- _groupPermissionsByUUID[GroupByUUIDKey(perms->getGroupID(), perms->getRank())] = _groupPermissions[idKey];
+ _groupPermissionsByUUID[GroupByUUIDKey(perms->getGroupID(), perms->getRankID())] = _groupPermissions[idKey];
needPack |= setGroupID(perms->getID(), perms->getGroupID());
}
}
@@ -481,7 +501,7 @@ void DomainServerSettingsManager::unpackPermissions() {
}
if (perms->isGroup()) {
// the group-id was cached. hook-up the uuid in the uuid->group hash
- _groupForbiddensByUUID[GroupByUUIDKey(perms->getGroupID(), perms->getRank())] = _groupForbiddens[idKey];
+ _groupForbiddensByUUID[GroupByUUIDKey(perms->getGroupID(), perms->getRankID())] = _groupForbiddens[idKey];
needPack |= setGroupID(perms->getID(), perms->getGroupID());
}
}
@@ -541,10 +561,10 @@ bool DomainServerSettingsManager::ensurePermissionsForGroupRanks() {
QList permissionGroupIDs = getGroupIDs();
foreach (QUuid groupID, permissionGroupIDs) {
QString groupName = _groupNames[groupID];
- int rankCountForGroup = _groupRanks[groupID].size();
- for (int rank = 0; rank < rankCountForGroup; rank++) {
- NodePermissionsKey nameKey = NodePermissionsKey(groupName, rank);
- GroupByUUIDKey idKey = GroupByUUIDKey(groupID, rank);
+ QHash& ranksForGroup = _groupRanks[groupID];
+ foreach (QUuid rankID, ranksForGroup.keys()) {
+ NodePermissionsKey nameKey = NodePermissionsKey(groupName, rankID);
+ GroupByUUIDKey idKey = GroupByUUIDKey(groupID, rankID);
NodePermissionsPointer perms;
if (_groupPermissions.contains(nameKey)) {
perms = _groupPermissions[nameKey];
@@ -561,10 +581,10 @@ bool DomainServerSettingsManager::ensurePermissionsForGroupRanks() {
QList forbiddenGroupIDs = getBlacklistGroupIDs();
foreach (QUuid groupID, forbiddenGroupIDs) {
QString groupName = _groupNames[groupID];
- int rankCountForGroup = _groupRanks[groupID].size();
- for (int rank = 0; rank < rankCountForGroup; rank++) {
- NodePermissionsKey nameKey = NodePermissionsKey(groupName, rank);
- GroupByUUIDKey idKey = GroupByUUIDKey(groupID, rank);
+ QHash& ranksForGroup = _groupRanks[groupID];
+ foreach (QUuid rankID, ranksForGroup.keys()) {
+ NodePermissionsKey nameKey = NodePermissionsKey(groupName, rankID);
+ GroupByUUIDKey idKey = GroupByUUIDKey(groupID, rankID);
NodePermissionsPointer perms;
if (_groupForbiddens.contains(nameKey)) {
perms = _groupForbiddens[nameKey];
@@ -610,8 +630,8 @@ NodePermissions DomainServerSettingsManager::getPermissionsForName(const QString
return nullPermissions;
}
-NodePermissions DomainServerSettingsManager::getPermissionsForGroup(const QString& groupName, int rank) const {
- NodePermissionsKey groupRankKey = NodePermissionsKey(groupName, rank);
+NodePermissions DomainServerSettingsManager::getPermissionsForGroup(const QString& groupName, QUuid rankID) const {
+ NodePermissionsKey groupRankKey = NodePermissionsKey(groupName, rankID);
if (_groupPermissions.contains(groupRankKey)) {
return *(_groupPermissions[groupRankKey].get());
}
@@ -620,8 +640,8 @@ NodePermissions DomainServerSettingsManager::getPermissionsForGroup(const QStrin
return nullPermissions;
}
-NodePermissions DomainServerSettingsManager::getPermissionsForGroup(const QUuid& groupID, int rank) const {
- GroupByUUIDKey byUUIDKey = GroupByUUIDKey(groupID, rank);
+NodePermissions DomainServerSettingsManager::getPermissionsForGroup(const QUuid& groupID, QUuid rankID) const {
+ GroupByUUIDKey byUUIDKey = GroupByUUIDKey(groupID, rankID);
if (!_groupPermissionsByUUID.contains(byUUIDKey)) {
NodePermissions nullPermissions;
nullPermissions.setAll(false);
@@ -631,8 +651,8 @@ NodePermissions DomainServerSettingsManager::getPermissionsForGroup(const QUuid&
return getPermissionsForGroup(groupKey.first, groupKey.second);
}
-NodePermissions DomainServerSettingsManager::getForbiddensForGroup(const QString& groupName, int rank) const {
- NodePermissionsKey groupRankKey = NodePermissionsKey(groupName, rank);
+NodePermissions DomainServerSettingsManager::getForbiddensForGroup(const QString& groupName, QUuid rankID) const {
+ NodePermissionsKey groupRankKey = NodePermissionsKey(groupName, rankID);
if (_groupForbiddens.contains(groupRankKey)) {
return *(_groupForbiddens[groupRankKey].get());
}
@@ -642,8 +662,8 @@ NodePermissions DomainServerSettingsManager::getForbiddensForGroup(const QString
return nullForbiddens;
}
-NodePermissions DomainServerSettingsManager::getForbiddensForGroup(const QUuid& groupID, int rank) const {
- GroupByUUIDKey byUUIDKey = GroupByUUIDKey(groupID, rank);
+NodePermissions DomainServerSettingsManager::getForbiddensForGroup(const QUuid& groupID, QUuid rankID) const {
+ GroupByUUIDKey byUUIDKey = GroupByUUIDKey(groupID, rankID);
if (!_groupForbiddensByUUID.contains(byUUIDKey)) {
NodePermissions nullForbiddens;
// XXX should this be setAll(true) ?
@@ -1042,9 +1062,14 @@ bool permissionVariantLessThan(const QVariant &v1, const QVariant &v2) {
return v1.toString() < v2.toString();
}
- if (m1.contains("rank_name") && m2.contains("rank_name") &&
+ // if (m1.contains("rank_name") && m2.contains("rank_name") &&
+ // m1["permissions_id"].toString() == m2["permissions_id"].toString()) {
+ // return m1["rank_name"].toString() < m2["rank_name"].toString();
+ // }
+
+ if (m1.contains("rank_order") && m2.contains("rank_order") &&
m1["permissions_id"].toString() == m2["permissions_id"].toString()) {
- return m1["rank_name"].toString() < m2["rank_name"].toString();
+ return m1["rank_order"].toInt() < m2["rank_order"].toInt();
}
return m1["permissions_id"].toString() < m2["permissions_id"].toString();
@@ -1062,6 +1087,16 @@ void DomainServerSettingsManager::sortPermissions() {
QList* permissionsList = reinterpret_cast(permissions);
std::sort((*permissionsList).begin(), (*permissionsList).end(), permissionVariantLessThan);
}
+ QVariant* groupPermissions = valueForKeyPath(_configMap.getUserConfig(), GROUP_PERMISSIONS_KEYPATH);
+ if (groupPermissions && groupPermissions->canConvert(QMetaType::QVariantList)) {
+ QList* permissionsList = reinterpret_cast(groupPermissions);
+ std::sort((*permissionsList).begin(), (*permissionsList).end(), permissionVariantLessThan);
+ }
+ QVariant* forbiddenPermissions = valueForKeyPath(_configMap.getUserConfig(), GROUP_FORBIDDENS_KEYPATH);
+ if (forbiddenPermissions && forbiddenPermissions->canConvert(QMetaType::QVariantList)) {
+ QList* permissionsList = reinterpret_cast(forbiddenPermissions);
+ std::sort((*permissionsList).begin(), (*permissionsList).end(), permissionVariantLessThan);
+ }
}
void DomainServerSettingsManager::persistToFile() {
@@ -1138,10 +1173,15 @@ void DomainServerSettingsManager::apiRefreshGroupInformation() {
return;
}
+ bool changed = false;
+
QStringList groupNames = getAllKnownGroupNames();
foreach (QString groupName, groupNames) {
- if (_groupIDs.contains(groupName.toLower())) {
- // we already know about this one
+ QString lowerGroupName = groupName.toLower();
+ if (_groupIDs.contains(lowerGroupName)) {
+ // we already know about this one. recall setGroupID in case the group has been
+ // added to another section (the same group is found in both groups and blacklists).
+ changed = setGroupID(groupName, _groupIDs[lowerGroupName]);
continue;
}
apiGetGroupID(groupName);
@@ -1151,6 +1191,12 @@ void DomainServerSettingsManager::apiRefreshGroupInformation() {
apiGetGroupRanks(groupID);
}
+ changed |= ensurePermissionsForGroupRanks();
+
+ if (changed) {
+ packPermissions();
+ }
+
unpackPermissions();
}
@@ -1222,8 +1268,6 @@ void DomainServerSettingsManager::apiGetGroupIDErrorCallback(QNetworkReply& requ
}
void DomainServerSettingsManager::apiGetGroupRanks(const QUuid& groupID) {
- _groupRanksLastFetched[groupID] = usecTimestampNow();
-
JSONCallbackParameters callbackParams;
callbackParams.jsonCallbackReceiver = this;
callbackParams.jsonCallbackMethod = "apiGetGroupRanksJSONCallback";
@@ -1278,18 +1322,32 @@ void DomainServerSettingsManager::apiGetGroupRanksJSONCallback(QNetworkReply& re
foreach (auto groupID, groups.keys()) {
QJsonObject group = groups[groupID].toObject();
QJsonArray ranks = group["ranks"].toArray();
+
+ QHash& ranksForGroup = _groupRanks[groupID];
+ QHash idsFromThisUpdate;
+
for (int rankIndex = 0; rankIndex < ranks.size(); rankIndex++) {
QJsonObject rank = ranks.at(rankIndex).toObject();
- QString rankName = rank["name"].toString();
+
+ QUuid rankID = QUuid(rank["id"].toString());
int rankOrder = rank["order"].toInt();
- QVector& ranksForGroup = _groupRanks[groupID];
- if (ranksForGroup.size() < rankOrder + 1) {
- ranksForGroup.resize(rankOrder + 1);
+ QString rankName = rank["name"].toString();
+ int rankMembersCount = rank["members_count"].toInt();
+
+ GroupRank groupRank(rankID, rankOrder, rankName, rankMembersCount);
+
+ if (ranksForGroup[rankID] != groupRank) {
+ ranksForGroup[rankID] = groupRank;
changed = true;
}
- if (ranksForGroup[rankOrder] != rankName) {
- ranksForGroup[rankOrder] = rankName;
- changed = true;
+
+ idsFromThisUpdate[rankID] = true;
+ }
+
+ // clean up any that went away
+ foreach (QUuid rankID, ranksForGroup.keys()) {
+ if (!idsFromThisUpdate.contains(rankID)) {
+ ranksForGroup.remove(rankID);
}
}
}
@@ -1307,20 +1365,20 @@ void DomainServerSettingsManager::apiGetGroupRanksErrorCallback(QNetworkReply& r
qDebug() << "******************** getGroupRanks api call failed:" << requestReply.error();
}
-void DomainServerSettingsManager::recordGroupMembership(const QString& name, const QUuid groupID, int rank) {
- if (rank >= 0) {
- _groupMembership[name][groupID] = rank;
+void DomainServerSettingsManager::recordGroupMembership(const QString& name, const QUuid groupID, QUuid rankID) {
+ if (rankID != QUuid()) {
+ _groupMembership[name][groupID] = rankID;
} else {
_groupMembership[name].remove(groupID);
}
}
-int DomainServerSettingsManager::isGroupMember(const QString& name, const QUuid& groupID) {
- const QHash& groupsForName = _groupMembership[name];
+QUuid DomainServerSettingsManager::isGroupMember(const QString& name, const QUuid& groupID) {
+ const QHash& groupsForName = _groupMembership[name];
if (groupsForName.contains(groupID)) {
return groupsForName[groupID];
}
- return -1;
+ return QUuid();
}
QList DomainServerSettingsManager::getGroupIDs() {
@@ -1370,9 +1428,10 @@ void DomainServerSettingsManager::debugDumpGroupsState() {
qDebug() << "_groupRanks:";
foreach (QUuid groupID, _groupRanks.keys()) {
- QVector& ranksForGroup = _groupRanks[groupID];
+ QHash& ranksForGroup = _groupRanks[groupID];
QString readableRanks;
- foreach (QString rankName, ranksForGroup) {
+ foreach (QUuid rankID, ranksForGroup.keys()) {
+ QString rankName = ranksForGroup[rankID].name;
if (readableRanks == "") {
readableRanks = rankName;
} else {
@@ -1381,4 +1440,14 @@ void DomainServerSettingsManager::debugDumpGroupsState() {
}
qDebug() << "| " << groupID << "==>" << readableRanks;
}
+
+ qDebug() << "_groupMembership";
+ foreach (QString userName, _groupMembership.keys()) {
+ QHash& groupsForUser = _groupMembership[userName];
+ QString line = "";
+ foreach (QUuid groupID, groupsForUser.keys()) {
+ line += " g=" + groupID.toString() + ",r=" + groupsForUser[groupID].toString();
+ }
+ qDebug() << "| " << userName << line;
+ }
}
diff --git a/domain-server/src/DomainServerSettingsManager.h b/domain-server/src/DomainServerSettingsManager.h
index f59d76bd1e..c4d70baf21 100644
--- a/domain-server/src/DomainServerSettingsManager.h
+++ b/domain-server/src/DomainServerSettingsManager.h
@@ -30,7 +30,8 @@ const QString AGENT_PERMISSIONS_KEYPATH = "security.permissions";
const QString GROUP_PERMISSIONS_KEYPATH = "security.group_permissions";
const QString GROUP_FORBIDDENS_KEYPATH = "security.group_forbiddens";
-using GroupByUUIDKey = QPair;
+using GroupByUUIDKey = QPair; // groupID, rankID
+
class DomainServerSettingsManager : public QObject {
Q_OBJECT
@@ -58,32 +59,34 @@ public:
QStringList getAllNames() const;
// these give access to permissions for specific groups from the domain-server settings page
- bool havePermissionsForGroup(const QString& groupName, int rank) const {
- return _groupPermissions.contains(groupName, rank);
+ bool havePermissionsForGroup(const QString& groupName, QUuid rankID) const {
+ return _groupPermissions.contains(groupName, rankID);
}
- NodePermissions getPermissionsForGroup(const QString& groupName, int rank) const;
- NodePermissions getPermissionsForGroup(const QUuid& groupID, int rank) const;
+ NodePermissions getPermissionsForGroup(const QString& groupName, QUuid rankID) const;
+ NodePermissions getPermissionsForGroup(const QUuid& groupID, QUuid rankID) const;
// these remove permissions from users in certain groups
- bool haveForbiddensForGroup(const QString& groupName, int rank) const { return _groupForbiddens.contains(groupName, rank); }
- NodePermissions getForbiddensForGroup(const QString& groupName, int rank) const;
- NodePermissions getForbiddensForGroup(const QUuid& groupID, int rank) const;
+ bool haveForbiddensForGroup(const QString& groupName, QUuid rankID) const {
+ return _groupForbiddens.contains(groupName, rankID);
+ }
+ NodePermissions getForbiddensForGroup(const QString& groupName, QUuid rankID) const;
+ NodePermissions getForbiddensForGroup(const QUuid& groupID, QUuid rankID) const;
QStringList getAllKnownGroupNames();
bool setGroupID(const QString& groupName, const QUuid& groupID);
+ GroupRank getGroupRank(QUuid groupID, QUuid rankID) { return _groupRanks[groupID][rankID]; }
QList getGroupIDs();
QList getBlacklistGroupIDs();
// these are used to locally cache the result of calling "api/v1/groups/.../is_member/..." on metaverse's api
void clearGroupMemberships(const QString& name) { _groupMembership[name].clear(); }
- void recordGroupMembership(const QString& name, const QUuid groupID, int rank);
- int isGroupMember(const QString& name, const QUuid& groupID); // returns rank or -1 if not a member
+ void recordGroupMembership(const QString& name, const QUuid groupID, QUuid rankID);
+ QUuid isGroupMember(const QString& name, const QUuid& groupID); // returns rank or -1 if not a member
// calls http api to refresh group information
void apiRefreshGroupInformation();
-
signals:
void updateNodePermissions();
@@ -138,11 +141,10 @@ private:
QHash _groupNames; // keep track of group-id to group-name mappings
// remember the responses to api/v1/groups/%1/ranks
- QHash> _groupRanks; // QHash>
- QHash _groupRanksLastFetched; // when did we last update _groupRanks
+ QHash> _groupRanks; // QHash>
// keep track of answers to api queries about which users are in which groups
- QHash> _groupMembership; // QHash>
+ QHash> _groupMembership; // QHash>
void debugDumpGroupsState();
diff --git a/libraries/networking/src/GroupRank.h b/libraries/networking/src/GroupRank.h
new file mode 100644
index 0000000000..89675684d8
--- /dev/null
+++ b/libraries/networking/src/GroupRank.h
@@ -0,0 +1,36 @@
+//
+// GroupRank.h
+// libraries/networking/src/
+//
+// Created by Seth Alves on 2016-7-21.
+// Copyright 2016 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#ifndef hifi_GroupRank_h
+#define hifi_GroupRank_h
+
+class GroupRank {
+public:
+ GroupRank() : id(QUuid()), order(-1), name(""), membersCount(-1) {}
+ GroupRank(QUuid id, unsigned int order, QString name, unsigned int membersCount) :
+ id(id), order(order), name(name), membersCount(membersCount) {}
+
+ QUuid id;
+ int order;
+ QString name;
+ int membersCount;
+};
+
+inline bool operator==(const GroupRank& lhs, const GroupRank& rhs) {
+ return
+ lhs.id == rhs.id &&
+ lhs.order == rhs.order &&
+ lhs.name == rhs.name &&
+ lhs.membersCount == rhs.membersCount;
+}
+inline bool operator!=(const GroupRank& lhs, const GroupRank& rhs) { return !(lhs == rhs); }
+
+#endif // hifi_GroupRank_h
diff --git a/libraries/networking/src/NodePermissions.cpp b/libraries/networking/src/NodePermissions.cpp
index 29b05fc837..c73ca122ff 100644
--- a/libraries/networking/src/NodePermissions.cpp
+++ b/libraries/networking/src/NodePermissions.cpp
@@ -32,8 +32,8 @@ NodePermissions::NodePermissions(QMap perms) {
_groupIDSet = true;
}
}
- if (perms.contains("rank")) {
- _rank = perms["rank"].toInt();
+ if (perms.contains("rank_id")) {
+ _rankID = QUuid(perms["rank_id"].toString());
}
permissions = NodePermissions::Permissions();
@@ -46,14 +46,15 @@ NodePermissions::NodePermissions(QMap perms) {
Permission::canConnectPastMaxCapacity : Permission::none;
}
-QVariant NodePermissions::toVariant(QVector rankNames) {
+QVariant NodePermissions::toVariant(QHash groupRanks) {
QMap values;
values["permissions_id"] = _id;
if (_groupIDSet) {
values["group_id"] = _groupID;
- values["rank"] = _rank;
- if (rankNames.size() > _rank) {
- values["rank_name"] = rankNames[_rank];
+ if (groupRanks.contains(_rankID)) {
+ values["rank_id"] = _rankID;
+ values["rank_name"] = groupRanks[_rankID].name;
+ values["rank_order"] = groupRanks[_rankID].order;
}
}
values["id_can_connect"] = can(Permission::canConnectToDomain);
@@ -147,7 +148,7 @@ QDataStream& operator>>(QDataStream& in, NodePermissions& perms) {
QDebug operator<<(QDebug debug, const NodePermissions& perms) {
debug.nospace() << "[permissions: " << perms.getID() << "/" << perms.getVerifiedUserName() << " -- ";
- debug.nospace() << "rank=" << perms.getRank()
+ debug.nospace() << "rank=" << perms.getRankID()
<< ", groupID=" << perms.getGroupID() << "/" << (perms.isGroup() ? "y" : "n");
if (perms.can(NodePermissions::Permission::canConnectToDomain)) {
debug << " connect";
diff --git a/libraries/networking/src/NodePermissions.h b/libraries/networking/src/NodePermissions.h
index 541f90aee8..6d12c4cf7e 100644
--- a/libraries/networking/src/NodePermissions.h
+++ b/libraries/networking/src/NodePermissions.h
@@ -18,21 +18,24 @@
#include
#include
+#include "GroupRank.h"
+
class NodePermissions;
using NodePermissionsPointer = std::shared_ptr;
-using NodePermissionsKey = QPair;
-using NodePermissionsKeyList = QList>;
+using NodePermissionsKey = QPair; // name, rankID
+using NodePermissionsKeyList = QList>;
+
class NodePermissions {
public:
- NodePermissions() { _id = QUuid::createUuid().toString(); _rank = 0; }
- NodePermissions(const QString& name) { _id = name.toLower(); _rank = 0; }
- NodePermissions(const NodePermissionsKey& key) { _id = key.first.toLower(); _rank = key.second; }
+ NodePermissions() { _id = QUuid::createUuid().toString(); _rankID = QUuid(); }
+ NodePermissions(const QString& name) { _id = name.toLower(); _rankID = QUuid(); }
+ NodePermissions(const NodePermissionsKey& key) { _id = key.first.toLower(); _rankID = key.second; }
NodePermissions(QMap perms);
QString getID() const { return _id; } // a user-name or a group-name, not verified
- int getRank() const { return _rank; }
- NodePermissionsKey getKey() const { return NodePermissionsKey(_id, _rank); }
+ QUuid getRankID() const { return _rankID; }
+ NodePermissionsKey getKey() const { return NodePermissionsKey(_id, _rankID); }
// the _id member isn't authenticated/verified and _username is.
void setVerifiedUserName(QString userName) { _verifiedUserName = userName.toLower(); }
@@ -63,7 +66,7 @@ public:
Q_DECLARE_FLAGS(Permissions, Permission)
Permissions permissions;
- QVariant toVariant(QVector rankNames = QVector());
+ QVariant toVariant(QHash groupRanks = QHash());
void setAll(bool value);
@@ -81,7 +84,7 @@ public:
protected:
QString _id;
- int _rank { 0 }; // 0 unless this is for a group
+ QUuid _rankID { QUuid() }; // 0 unless this is for a group
QString _verifiedUserName;
bool _groupIDSet { false };
@@ -107,7 +110,7 @@ public:
bool contains(const NodePermissionsKey& key) const {
return _data.contains(NodePermissionsKey(key.first.toLower(), key.second));
}
- bool contains(const QString& keyFirst, int keySecond) const {
+ bool contains(const QString& keyFirst, QUuid keySecond) const {
return _data.contains(NodePermissionsKey(keyFirst.toLower(), keySecond));
}
QList keys() const { return _data.keys(); }