add a permissions-grid row for friends-of-domain-owner

This commit is contained in:
Seth Alves 2016-06-24 11:42:56 -07:00
parent c4b0f1899e
commit cc1b6f0cb2
7 changed files with 87 additions and 22 deletions

View file

@ -142,6 +142,12 @@ NodePermissions DomainGatekeeper::applyPermissionsForUser(bool isLocalUser,
userPerms |= _server->_settingsManager.getStandardPermissionsForName(NodePermissions::standardNameLoggedIn);
qDebug() << "user-permissions: user is logged-into metavers, so:" << userPerms;
// if this user is a friend of the domain-owner, give them friend's permissions
if (_domainOwnerFriends.contains(verifiedUsername)) {
userPerms |= _server->_settingsManager.getStandardPermissionsForName(NodePermissions::standardNameFriends);
qDebug() << "user-permissions: user is friends with domain-owner, so:" << userPerms;
}
// if this user is a known member of a group, give them the implied permissions
foreach (QUuid groupID, _server->_settingsManager.getKnownGroupIDs()) {
if (groupID.isNull()) {
@ -275,6 +281,7 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
// ask for their public key right now to make sure we have it
requestUserPublicKey(username);
getGroupMemberships(username); // optimistically get started on group memberships
getDomainOwnerFriendsList();
return SharedNodePointer();
}
@ -284,6 +291,7 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
userPerms.setUserName(username);
verifiedUsername = username;
getGroupMemberships(username);
getDomainOwnerFriendsList();
} else if (!username.isEmpty()) {
// they sent us a username, but it didn't check out
requestUserPublicKey(username);
@ -717,5 +725,39 @@ void DomainGatekeeper::getIsGroupMemberJSONCallback(QNetworkReply& requestReply)
}
void DomainGatekeeper::getIsGroupMemberErrorCallback(QNetworkReply& requestReply) {
qDebug() << "getGroupID api call failed:" << requestReply.error();
qDebug() << "getIsGroupMember api call failed:" << requestReply.error();
}
void DomainGatekeeper::getDomainOwnerFriendsList() {
JSONCallbackParameters callbackParams;
callbackParams.jsonCallbackReceiver = this;
callbackParams.jsonCallbackMethod = "getDomainOwnerFriendsListJSONCallback";
callbackParams.errorCallbackReceiver = this;
callbackParams.errorCallbackMethod = "getDomainOwnerFriendsListErrorCallback";
const QString GET_FRIENDS_LIST_PATH = "api/v1/users";
QUrlQuery query;
query.addQueryItem("filter", "friends");
DependencyManager::get<AccountManager>()->sendRequest(GET_FRIENDS_LIST_PATH, AccountManagerAuth::Required,
QNetworkAccessManager::GetOperation, callbackParams, QByteArray(),
NULL, QVariantMap(), query);
}
void DomainGatekeeper::getDomainOwnerFriendsListJSONCallback(QNetworkReply& requestReply) {
QJsonObject jsonObject = QJsonDocument::fromJson(requestReply.readAll()).object();
if (jsonObject["status"].toString() == "success") {
_domainOwnerFriends.clear();
QJsonArray friends = jsonObject["data"].toObject()["users"].toArray();
for (int i = 0; i < friends.size(); i++) {
QString friendUserName = friends.at(i).toObject()["username"].toString();
_domainOwnerFriends[friendUserName] = true;
}
} else {
qDebug() << "getDomainOwnerFriendsList api call returned:" << QJsonDocument(jsonObject).toJson(QJsonDocument::Compact);
}
}
void DomainGatekeeper::getDomainOwnerFriendsListErrorCallback(QNetworkReply& requestReply) {
qDebug() << "getDomainOwnerFriendsList api call failed:" << requestReply.error();
}

View file

@ -56,6 +56,9 @@ public slots:
void getIsGroupMemberJSONCallback(QNetworkReply& requestReply);
void getIsGroupMemberErrorCallback(QNetworkReply& requestReply);
void getDomainOwnerFriendsListJSONCallback(QNetworkReply& requestReply);
void getDomainOwnerFriendsListErrorCallback(QNetworkReply& requestReply);
signals:
void killNode(SharedNodePointer node);
void connectedNode(SharedNodePointer node);
@ -98,10 +101,12 @@ private:
QHash<QString, QUuid> _connectionTokenHash;
QHash<QString, QByteArray> _userPublicKeys;
QHash<QString, bool> _inFlightPublicKeyRequests; // keep track of which we've already asked for
QHash<QString, bool> _domainOwnerFriends; // keep track of friends of the domain owner
NodePermissions applyPermissionsForUser(bool isLocalUser, NodePermissions userPerms, QString verifiedUsername);
void getGroupMemberships(const QString& username);
void getIsGroupMember(const QString& username, const QUuid groupID);
void getDomainOwnerFriendsList();
};

View file

@ -218,6 +218,8 @@ void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList
new NodePermissions(NodePermissions::standardNameAnonymous));
_standardAgentPermissions[NodePermissions::standardNameLoggedIn].reset(
new NodePermissions(NodePermissions::standardNameLoggedIn));
_standardAgentPermissions[NodePermissions::standardNameFriends].reset(
new NodePermissions(NodePermissions::standardNameFriends));
if (isRestrictedAccess) {
// only users in allow-users list can connect
@ -340,6 +342,7 @@ void DomainServerSettingsManager::unpackPermissions() {
bool foundLocalhost = false;
bool foundAnonymous = false;
bool foundLoggedIn = false;
bool foundFriends = false;
bool needPack = false;
QVariant* standardPermissions = valueForKeyPath(_configMap.getUserConfig(), AGENT_STANDARD_PERMISSIONS_KEYPATH);
@ -368,6 +371,7 @@ void DomainServerSettingsManager::unpackPermissions() {
foundLocalhost |= (id == NodePermissions::standardNameLocalhost);
foundAnonymous |= (id == NodePermissions::standardNameAnonymous);
foundLoggedIn |= (id == NodePermissions::standardNameLoggedIn);
foundFriends |= (id == NodePermissions::standardNameFriends);
if (_standardAgentPermissions.contains(id)) {
qDebug() << "duplicate name in standard permissions table: " << id;
_standardAgentPermissions[id] |= perms;
@ -424,6 +428,11 @@ void DomainServerSettingsManager::unpackPermissions() {
_standardAgentPermissions[perms->getID()] = perms;
needPack = true;
}
if (!foundFriends) {
NodePermissionsPointer perms { new NodePermissions(NodePermissions::standardNameFriends) };
_standardAgentPermissions[perms->getID()] = perms;
needPack = true;
}
if (needPack) {
packPermissions();

View file

@ -200,8 +200,9 @@ void AccountManager::sendRequest(const QString& path,
const JSONCallbackParameters& callbackParams,
const QByteArray& dataByteArray,
QHttpMultiPart* dataMultiPart,
const QVariantMap& propertyMap) {
const QVariantMap& propertyMap,
QUrlQuery query) {
if (thread() != QThread::currentThread()) {
QMetaObject::invokeMethod(this, "sendRequest",
Q_ARG(const QString&, path),
@ -213,9 +214,9 @@ void AccountManager::sendRequest(const QString& path,
Q_ARG(QVariantMap, propertyMap));
return;
}
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
QNetworkRequest networkRequest;
networkRequest.setHeader(QNetworkRequest::UserAgentHeader, _userAgentGetter());
@ -228,13 +229,17 @@ void AccountManager::sendRequest(const QString& path,
}
QUrl requestURL = _authURL;
if (path.startsWith("/")) {
requestURL.setPath(path);
} else {
requestURL.setPath("/" + path);
}
if (!query.isEmpty()) {
requestURL.setQuery(query);
}
if (authType != AccountManagerAuth::None ) {
if (hasValidAccessToken()) {
networkRequest.setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER,
@ -245,22 +250,21 @@ void AccountManager::sendRequest(const QString& path,
<< path << "that requires authentication";
return;
}
}
}
networkRequest.setUrl(requestURL);
if (VERBOSE_HTTP_REQUEST_DEBUGGING) {
qCDebug(networking) << "Making a request to" << qPrintable(requestURL.toString());
if (!dataByteArray.isEmpty()) {
qCDebug(networking) << "The POST/PUT body -" << QString(dataByteArray);
}
}
QNetworkReply* networkReply = NULL;
switch (operation) {
case QNetworkAccessManager::GetOperation:
networkReply = networkAccessManager.get(networkRequest);
@ -273,7 +277,7 @@ void AccountManager::sendRequest(const QString& path,
} else {
networkReply = networkAccessManager.put(networkRequest, dataMultiPart);
}
// make sure dataMultiPart is destroyed when the reply is
connect(networkReply, &QNetworkReply::destroyed, dataMultiPart, &QHttpMultiPart::deleteLater);
} else {
@ -284,7 +288,7 @@ void AccountManager::sendRequest(const QString& path,
networkReply = networkAccessManager.put(networkRequest, dataByteArray);
}
}
break;
case QNetworkAccessManager::DeleteOperation:
networkReply = networkAccessManager.sendCustomRequest(networkRequest, "DELETE");
@ -293,7 +297,7 @@ void AccountManager::sendRequest(const QString& path,
// other methods not yet handled
break;
}
if (networkReply) {
if (!propertyMap.isEmpty()) {
// we have properties to set on the reply so the user can check them after
@ -301,18 +305,18 @@ void AccountManager::sendRequest(const QString& path,
networkReply->setProperty(qPrintable(propertyKey), propertyMap.value(propertyKey));
}
}
if (!callbackParams.isEmpty()) {
// if we have information for a callback, insert the callbackParams into our local map
_pendingCallbackMap.insert(networkReply, callbackParams);
if (callbackParams.updateReciever && !callbackParams.updateSlot.isEmpty()) {
callbackParams.updateReciever->connect(networkReply, SIGNAL(uploadProgress(qint64, qint64)),
callbackParams.updateSlot.toStdString().c_str());
}
}
// if we ended up firing of a request, hook up to it now
connect(networkReply, SIGNAL(finished()), SLOT(processReply()));
}

View file

@ -16,6 +16,7 @@
#include <QtCore/QObject>
#include <QtCore/QUrl>
#include <QtNetwork/QNetworkReply>
#include <QUrlQuery>
#include "NetworkAccessManager.h"
@ -67,7 +68,8 @@ public:
const JSONCallbackParameters& callbackParams = JSONCallbackParameters(),
const QByteArray& dataByteArray = QByteArray(),
QHttpMultiPart* dataMultiPart = NULL,
const QVariantMap& propertyMap = QVariantMap());
const QVariantMap& propertyMap = QVariantMap(),
QUrlQuery query = QUrlQuery());
void setIsAgent(bool isAgent) { _isAgent = isAgent; }

View file

@ -16,11 +16,13 @@
QString NodePermissions::standardNameLocalhost = QString("localhost");
QString NodePermissions::standardNameLoggedIn = QString("logged-in");
QString NodePermissions::standardNameAnonymous = QString("anonymous");
QString NodePermissions::standardNameFriends = QString("friends");
QStringList NodePermissions::standardNames = QList<QString>()
<< NodePermissions::standardNameLocalhost
<< NodePermissions::standardNameLoggedIn
<< NodePermissions::standardNameAnonymous;
<< NodePermissions::standardNameAnonymous
<< NodePermissions::standardNameFriends;
NodePermissions::NodePermissions(QMap<QString, QVariant> perms) {
_id = perms["permissions_id"].toString();

View file

@ -43,6 +43,7 @@ public:
static QString standardNameLocalhost;
static QString standardNameLoggedIn;
static QString standardNameAnonymous;
static QString standardNameFriends;
static QStringList standardNames;
// the initializations here should match the defaults in describe-settings.json