mirror of
https://github.com/overte-org/overte.git
synced 2025-04-12 07:11:34 +02:00
Update to work with WordPress plugin
This commit is contained in:
parent
7da91d9557
commit
bc56eb5ac7
5 changed files with 36 additions and 46 deletions
|
@ -77,13 +77,6 @@
|
|||
"type": "checkbox",
|
||||
"advanced": true
|
||||
},
|
||||
{
|
||||
"name": "domain_access_token",
|
||||
"label": "Domain API Access Token",
|
||||
"help": "This is the access token that your domain-server will use to verify users and their roles. This token must grant access to that permission set on your REST API server.",
|
||||
"advanced": true,
|
||||
"backup": false
|
||||
},
|
||||
{
|
||||
"name": "oauth2_url_path",
|
||||
"label": "Authentication URL",
|
||||
|
@ -95,6 +88,13 @@
|
|||
"label": "WordPress API URL Base",
|
||||
"help": "The URL base that the domain server will use to make WordPress API calls. Typically \"https://oursite.com/wp-json/\". However, if using non-pretty permalinks or otherwise get a 404 error then try \"https://oursite.com/?rest_route=/\".",
|
||||
"advanced": true
|
||||
},
|
||||
{
|
||||
"name": "plugin_client_id",
|
||||
"label": "WordPress Plugin Client ID",
|
||||
"help": "This is the client ID from the WordPress plugin configuration.",
|
||||
"advanced": true,
|
||||
"backup": false
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -453,6 +453,7 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo
|
|||
const QString AUTHENTICATION_ENAABLED = "authentication.enable_oauth2";
|
||||
const QString AUTHENTICATION_OAUTH2_URL_PATH = "authentication.oauth2_url_path";
|
||||
const QString AUTHENTICATION_WORDPRESS_URL_BASE = "authentication.wordpress_url_base";
|
||||
const QString AUTHENTICATION_PLUGIN_CLIENT_ID = "authentication.plugin_client_id";
|
||||
const QString MAXIMUM_USER_CAPACITY = "security.maximum_user_capacity";
|
||||
const QString MAXIMUM_USER_CAPACITY_REDIRECT_LOCATION = "security.maximum_user_capacity_redirect_location";
|
||||
|
||||
|
@ -553,8 +554,15 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
|
|||
if (domainAuthURLVariant.canConvert<QString>()) {
|
||||
domainAuthURL = domainAuthURLVariant.toString();
|
||||
}
|
||||
QString domainAuthClientID;
|
||||
auto domainAuthClientIDVariant = _server->_settingsManager.valueForKeyPath(AUTHENTICATION_PLUGIN_CLIENT_ID);
|
||||
if (domainAuthClientIDVariant.canConvert<QString>()) {
|
||||
domainAuthClientID = domainAuthClientIDVariant.toString();
|
||||
}
|
||||
|
||||
sendConnectionDeniedPacket("You lack the required domain permissions to connect to this domain.",
|
||||
nodeConnection.senderSockAddr, DomainHandler::ConnectionRefusedReason::NotAuthorizedDomain, domainAuthURL);
|
||||
nodeConnection.senderSockAddr, DomainHandler::ConnectionRefusedReason::NotAuthorizedDomain,
|
||||
domainAuthURL + "|" + domainAuthClientID);
|
||||
} else {
|
||||
sendConnectionDeniedPacket("You lack the required metaverse permissions to connect to this domain.",
|
||||
nodeConnection.senderSockAddr, DomainHandler::ConnectionRefusedReason::NotAuthorizedMetaverse);
|
||||
|
@ -1242,11 +1250,9 @@ void DomainGatekeeper::requestDomainUser(const QString& username, const QString&
|
|||
}
|
||||
|
||||
// Get data pertaining to "me", the user who generated the access token.
|
||||
// ####### TODO: Confirm API route and data w.r.t. OAuth2 plugin's capabilities. [plugin]
|
||||
const QString WORDPRESS_USER_ROUTE = "wp/v2/users/me?context=edit&_fields=id,username,roles";
|
||||
QUrl domainUserURL = apiBase + WORDPRESS_USER_ROUTE;
|
||||
|
||||
// ####### TODO: Append a random key to check in response? [security]
|
||||
const QString WORDPRESS_USER_ROUTE = "wp/v2/users/me";
|
||||
const QString WORDPRESS_USER_QUERY = "_fields=username,roles";
|
||||
QUrl domainUserURL = apiBase + WORDPRESS_USER_ROUTE + (apiBase.contains("?") ? "&" : "?") + WORDPRESS_USER_QUERY;
|
||||
|
||||
QNetworkRequest request;
|
||||
|
||||
|
@ -1275,34 +1281,24 @@ void DomainGatekeeper::requestDomainUserFinished() {
|
|||
auto httpStatus = requestReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
|
||||
if (200 <= httpStatus && httpStatus < 300) {
|
||||
// Success.
|
||||
// ####### TODO: Verify Expected response. [plugin]
|
||||
/*
|
||||
{
|
||||
id: 2,
|
||||
username : 'apiuser',
|
||||
roles : ['subscriber'] ,
|
||||
}
|
||||
*/
|
||||
|
||||
QString username = rootObject["username"].toString().toLower();
|
||||
if (_inFlightDomainUserIdentityRequests.contains(username)) {
|
||||
// Success! Verified user.
|
||||
_verifiedDomainUserIdentities.insert(username, _inFlightDomainUserIdentityRequests.value(username));
|
||||
_inFlightDomainUserIdentityRequests.remove(username);
|
||||
|
||||
// ####### TODO: Handle roles.
|
||||
|
||||
} else {
|
||||
// Failure.
|
||||
qDebug() << "Unexpected username in response for user details -" << username;
|
||||
}
|
||||
|
||||
// ####### TODO: Handle roles if available. [plugin]
|
||||
|
||||
} else {
|
||||
// Failure.
|
||||
|
||||
// ####### TODO: Error fields to report. [plugin]
|
||||
qDebug() << "Error in response for user details -" << httpStatus << requestReply->error()
|
||||
<< "-" << rootObject["error"].toString();
|
||||
<< "-" << rootObject["error"].toString() << rootObject["error_description"].toString();
|
||||
|
||||
_inFlightDomainUserIdentityRequests.clear();
|
||||
}
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
// FIXME: Generalize to other OAuth2 sources for domain login.
|
||||
|
||||
const bool VERBOSE_HTTP_REQUEST_DEBUGGING = false;
|
||||
const QString DOMAIN_ACCOUNT_MANAGER_REQUESTED_SCOPE = "foo bar"; // ####### TODO: WordPress plugin's required scope. [plugin]
|
||||
// ####### TODO: Should scope be configured in domain server settings? [plugin]
|
||||
|
||||
// ####### TODO: Add storing domain URL and check against it when retrieving values?
|
||||
// ####### TODO: Add storing _authURL and check against it when retrieving values?
|
||||
|
@ -71,15 +69,15 @@ void DomainAccountManager::requestAccessToken(const QString& username, const QSt
|
|||
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader, NetworkingConstants::VIRCADIA_USER_AGENT);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
// ####### TODO: WordPress plugin's authorization requirements. [plugin]
|
||||
request.setRawHeader(QByteArray("Authorization"), QByteArray("Basic b2F1dGgtY2xpZW50LTE6b2F1dGgtY2xpZW50LXNlY3JldC0x"));
|
||||
|
||||
// miniOrange WordPress API Authentication plugin:
|
||||
// - Requires "client_id" parameter.
|
||||
// - Ignores "state" parameter.
|
||||
QByteArray formData;
|
||||
formData.append("grant_type=password&");
|
||||
formData.append("username=" + QUrl::toPercentEncoding(username) + "&");
|
||||
formData.append("password=" + QUrl::toPercentEncoding(password) + "&");
|
||||
formData.append("scope=" + DOMAIN_ACCOUNT_MANAGER_REQUESTED_SCOPE);
|
||||
// ####### TODO: Include state? [plugin]
|
||||
formData.append("client_id=" + _clientID);
|
||||
|
||||
request.setUrl(_authURL);
|
||||
|
||||
|
@ -100,20 +98,13 @@ void DomainAccountManager::requestAccessTokenFinished() {
|
|||
auto httpStatus = requestReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
if (200 <= httpStatus && httpStatus < 300) {
|
||||
|
||||
// ####### TODO: Process response state? [plugin]
|
||||
// ####### TODO: Process response scope? [plugin]
|
||||
|
||||
// ####### TODO: Which method are the tokens provided in? [plugin]
|
||||
// miniOrange plugin provides no scope.
|
||||
if (rootObject.contains("access_token")) {
|
||||
// Success.
|
||||
|
||||
QUrl rootURL = requestReply->url();
|
||||
rootURL.setPath("");
|
||||
|
||||
setTokensFromJSON(rootObject, rootURL);
|
||||
|
||||
emit loginComplete();
|
||||
|
||||
} else {
|
||||
// Failure.
|
||||
qCDebug(networking) << "Received a response for password grant that is missing one or more expected values.";
|
||||
|
@ -122,10 +113,8 @@ void DomainAccountManager::requestAccessTokenFinished() {
|
|||
|
||||
} else {
|
||||
// Failure.
|
||||
|
||||
// ####### TODO: Error object fields to report. [plugin]
|
||||
qCDebug(networking) << "Error in response for password grant -" << httpStatus << requestReply->error()
|
||||
<< "_" << rootObject["error"].toString();
|
||||
qCDebug(networking) << "Error in response for password grant -" << httpStatus << requestReply->error()
|
||||
<< "-" << rootObject["error"].toString() << rootObject["error_description"].toString();
|
||||
emit loginFailed();
|
||||
}
|
||||
}
|
||||
|
@ -173,6 +162,7 @@ void DomainAccountManager::setTokensFromJSON(const QJsonObject& jsonObject, cons
|
|||
|
||||
// ####### TODO: Enable and use these.
|
||||
// ####### TODO: Protect these per AccountManager?
|
||||
// ######: TODO: clientID needed?
|
||||
/*
|
||||
qCDebug(networking) << "Storing a domain account with access-token for" << qPrintable(url.toString());
|
||||
domainAccessToken.set(jsonObject["access_token"].toString());
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
DomainAccountManager();
|
||||
|
||||
void setAuthURL(const QUrl& authURL);
|
||||
void setClientID(const QString& clientID) { _clientID = clientID; }
|
||||
|
||||
QString getUsername() { return _username; }
|
||||
QString getAccessToken() { return _access_token; }
|
||||
|
@ -51,6 +52,7 @@ private:
|
|||
void sendInterfaceAccessTokenToServer();
|
||||
|
||||
QUrl _authURL;
|
||||
QString _clientID;
|
||||
QString _username; // ####### TODO: Store elsewhere?
|
||||
QString _access_token; // ####... ""
|
||||
QString _refresh_token; // ####... ""
|
||||
|
|
|
@ -589,7 +589,9 @@ void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointer<Rec
|
|||
|
||||
auto accountManager = DependencyManager::get<DomainAccountManager>();
|
||||
if (!extraInfo.isEmpty()) {
|
||||
accountManager->setAuthURL(extraInfo);
|
||||
auto extraInfoComponents = extraInfo.split("|");
|
||||
accountManager->setAuthURL(extraInfoComponents.value(0));
|
||||
accountManager->setClientID(extraInfoComponents.value(1));
|
||||
}
|
||||
|
||||
if (!_hasCheckedForDomainAccessToken) {
|
||||
|
|
Loading…
Reference in a new issue