forked from loafle/openapi-generator-original
[Qt][C++] Oauth2 Authorization Code Flow and Implicit Flow Support. (#10183)
* Oauth class with reply server for authorization flow * multiple scopes. Joined with space seperator * some refactoring, using urls from the spec * added implicit flow. Refactored oauth classes. * added missing {{prefix}} to Oauth class * added client credentials flow * added password flow. setVariables for each class * Refactored variables to fit style. Updated Samples
This commit is contained in:
parent
e7c3bdacc2
commit
f596b32316
@ -236,10 +236,10 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
|||||||
|ApiKey|✓|OAS2,OAS3
|
|ApiKey|✓|OAS2,OAS3
|
||||||
|OpenIDConnect|✗|OAS3
|
|OpenIDConnect|✗|OAS3
|
||||||
|BearerToken|✓|OAS3
|
|BearerToken|✓|OAS3
|
||||||
|OAuth2_Implicit|✗|OAS2,OAS3
|
|OAuth2_Implicit|✓|OAS2,OAS3
|
||||||
|OAuth2_Password|✗|OAS2,OAS3
|
|OAuth2_Password|✓|OAS2,OAS3
|
||||||
|OAuth2_ClientCredentials|✗|OAS2,OAS3
|
|OAuth2_ClientCredentials|✓|OAS2,OAS3
|
||||||
|OAuth2_AuthorizationCode|✗|OAS2,OAS3
|
|OAuth2_AuthorizationCode|✓|OAS2,OAS3
|
||||||
|
|
||||||
### Wire Format Feature
|
### Wire Format Feature
|
||||||
| Name | Supported | Defined By |
|
| Name | Supported | Defined By |
|
||||||
|
@ -46,6 +46,10 @@ public class CppQtClientCodegen extends CppQtAbstractCodegen implements CodegenC
|
|||||||
.includeSecurityFeatures(SecurityFeature.BasicAuth)
|
.includeSecurityFeatures(SecurityFeature.BasicAuth)
|
||||||
.includeSecurityFeatures(SecurityFeature.ApiKey)
|
.includeSecurityFeatures(SecurityFeature.ApiKey)
|
||||||
.includeSecurityFeatures(SecurityFeature.BearerToken)
|
.includeSecurityFeatures(SecurityFeature.BearerToken)
|
||||||
|
.includeSecurityFeatures(SecurityFeature.OAuth2_AuthorizationCode)
|
||||||
|
.includeSecurityFeatures(SecurityFeature.OAuth2_Implicit)
|
||||||
|
.includeSecurityFeatures(SecurityFeature.OAuth2_ClientCredentials)
|
||||||
|
.includeSecurityFeatures(SecurityFeature.OAuth2_Password)
|
||||||
.includeGlobalFeatures(GlobalFeature.ParameterStyling)
|
.includeGlobalFeatures(GlobalFeature.ParameterStyling)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -96,6 +100,8 @@ public class CppQtClientCodegen extends CppQtAbstractCodegen implements CodegenC
|
|||||||
supportingFiles.add(new SupportingFile("enum.mustache", sourceFolder, PREFIX + "Enum.h"));
|
supportingFiles.add(new SupportingFile("enum.mustache", sourceFolder, PREFIX + "Enum.h"));
|
||||||
supportingFiles.add(new SupportingFile("ServerConfiguration.mustache", sourceFolder, PREFIX + "ServerConfiguration.h"));
|
supportingFiles.add(new SupportingFile("ServerConfiguration.mustache", sourceFolder, PREFIX + "ServerConfiguration.h"));
|
||||||
supportingFiles.add(new SupportingFile("ServerVariable.mustache", sourceFolder, PREFIX + "ServerVariable.h"));
|
supportingFiles.add(new SupportingFile("ServerVariable.mustache", sourceFolder, PREFIX + "ServerVariable.h"));
|
||||||
|
supportingFiles.add(new SupportingFile("oauth.cpp.mustache", sourceFolder, PREFIX + "Oauth.cpp"));
|
||||||
|
supportingFiles.add(new SupportingFile("oauth.h.mustache", sourceFolder, PREFIX + "Oauth.h"));
|
||||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||||
supportingFiles.add(new SupportingFile("CMakeLists.txt.mustache", sourceFolder, "CMakeLists.txt"));
|
supportingFiles.add(new SupportingFile("CMakeLists.txt.mustache", sourceFolder, "CMakeLists.txt"));
|
||||||
if (optionalProjectFileFlag) {
|
if (optionalProjectFileFlag) {
|
||||||
@ -127,6 +133,8 @@ public class CppQtClientCodegen extends CppQtAbstractCodegen implements CodegenC
|
|||||||
supportingFiles.add(new SupportingFile("enum.mustache", sourceFolder, modelNamePrefix + "Enum.h"));
|
supportingFiles.add(new SupportingFile("enum.mustache", sourceFolder, modelNamePrefix + "Enum.h"));
|
||||||
supportingFiles.add(new SupportingFile("ServerConfiguration.mustache", sourceFolder, modelNamePrefix + "ServerConfiguration.h"));
|
supportingFiles.add(new SupportingFile("ServerConfiguration.mustache", sourceFolder, modelNamePrefix + "ServerConfiguration.h"));
|
||||||
supportingFiles.add(new SupportingFile("ServerVariable.mustache", sourceFolder, modelNamePrefix + "ServerVariable.h"));
|
supportingFiles.add(new SupportingFile("ServerVariable.mustache", sourceFolder, modelNamePrefix + "ServerVariable.h"));
|
||||||
|
supportingFiles.add(new SupportingFile("oauth.cpp.mustache", sourceFolder, modelNamePrefix + "Oauth.cpp"));
|
||||||
|
supportingFiles.add(new SupportingFile("oauth.h.mustache", sourceFolder, modelNamePrefix + "Oauth.h"));
|
||||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||||
supportingFiles.add(new SupportingFile("CMakeLists.txt.mustache", sourceFolder, "CMakeLists.txt"));
|
supportingFiles.add(new SupportingFile("CMakeLists.txt.mustache", sourceFolder, "CMakeLists.txt"));
|
||||||
|
|
||||||
|
@ -22,7 +22,8 @@ HEADERS += \
|
|||||||
$${PWD}/{{prefix}}Enum.h \
|
$${PWD}/{{prefix}}Enum.h \
|
||||||
$${PWD}/{{prefix}}HttpFileElement.h \
|
$${PWD}/{{prefix}}HttpFileElement.h \
|
||||||
$${PWD}/{{prefix}}ServerConfiguration.h \
|
$${PWD}/{{prefix}}ServerConfiguration.h \
|
||||||
$${PWD}/{{prefix}}ServerVariable.h
|
$${PWD}/{{prefix}}ServerVariable.h \
|
||||||
|
$${PWD}/{{prefix}}Oauth.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
# Models
|
# Models
|
||||||
@ -42,4 +43,5 @@ SOURCES += \
|
|||||||
# Others
|
# Others
|
||||||
$${PWD}/{{prefix}}Helpers.cpp \
|
$${PWD}/{{prefix}}Helpers.cpp \
|
||||||
$${PWD}/{{prefix}}HttpRequest.cpp \
|
$${PWD}/{{prefix}}HttpRequest.cpp \
|
||||||
$${PWD}/{{prefix}}HttpFileElement.cpp
|
$${PWD}/{{prefix}}HttpFileElement.cpp \
|
||||||
|
$${PWD}/{{prefix}}Oauth.cpp
|
||||||
|
@ -678,8 +678,128 @@ void {{classname}}::{{nickname}}({{#allParams}}{{#required}}const {{{dataType}}}
|
|||||||
if (findChildren<{{prefix}}HttpRequestWorker*>().count() == 0) {
|
if (findChildren<{{prefix}}HttpRequestWorker*>().count() == 0) {
|
||||||
emit allPendingRequestsCompleted();
|
emit allPendingRequestsCompleted();
|
||||||
}
|
}
|
||||||
|
});{{#authMethods}}{{#isOAuth}}{{#isCode}}
|
||||||
|
_OauthMethod = 2;
|
||||||
|
_implicitFlow.unlink();
|
||||||
|
_credentialFlow.unlink();
|
||||||
|
_passwordFlow.unlink();
|
||||||
|
_authFlow.link();
|
||||||
|
QStringList scope;
|
||||||
|
{{#scopes}}
|
||||||
|
scope.append("{{scope}}");
|
||||||
|
{{/scopes}}
|
||||||
|
auto token = _authFlow.getToken(scope.join(" "));
|
||||||
|
if(token.isValid())
|
||||||
|
input.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
|
||||||
|
_latestWorker = new {{prefix}}HttpRequestWorker(this, _manager);
|
||||||
|
_latestWorker->setTimeOut(_timeOut);
|
||||||
|
_latestWorker->setWorkingDirectory(_workingDirectory);{{#contentCompression}}
|
||||||
|
_latestWorker->setResponseCompressionEnabled(isResponseCompressionEnabled);
|
||||||
|
_latestWorker->setRequestCompressionEnabled(isRequestCompressionEnabled);{{/contentCompression}}
|
||||||
|
|
||||||
|
connect(_latestWorker, &{{prefix}}HttpRequestWorker::on_execution_finished, this, &{{classname}}::{{nickname}}Callback);
|
||||||
|
connect(this, &{{classname}}::abortRequestsSignal, _latestWorker, &QObject::deleteLater);
|
||||||
|
connect(_latestWorker, &QObject::destroyed, [this](){
|
||||||
|
if(findChildren<{{prefix}}HttpRequestWorker*>().count() == 0){
|
||||||
|
emit allPendingRequestsCompleted();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_latestInput = input;
|
||||||
|
_latestScope = scope;{{/isCode}}
|
||||||
|
{{#isImplicit}}
|
||||||
|
_OauthMethod = 1;
|
||||||
|
_implicitFlow.link();
|
||||||
|
_passwordFlow.unlink();
|
||||||
|
_authFlow.unlink();
|
||||||
|
_credentialFlow.unlink();
|
||||||
|
QStringList scope;
|
||||||
|
{{#scopes}}
|
||||||
|
scope.append("{{scope}}");
|
||||||
|
{{/scopes}}
|
||||||
|
auto token = _implicitFlow.getToken(scope.join(" "));
|
||||||
|
if(token.isValid())
|
||||||
|
input.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
|
||||||
|
_latestWorker = new {{prefix}}HttpRequestWorker(this, _manager);
|
||||||
|
_latestWorker->setTimeOut(_timeOut);
|
||||||
|
_latestWorker->setWorkingDirectory(_workingDirectory);{{#contentCompression}}
|
||||||
|
_latestWorker->setResponseCompressionEnabled(isResponseCompressionEnabled);
|
||||||
|
_latestWorker->setRequestCompressionEnabled(isRequestCompressionEnabled);{{/contentCompression}}
|
||||||
|
|
||||||
|
connect(_latestWorker, &{{prefix}}HttpRequestWorker::on_execution_finished, this, &{{classname}}::{{nickname}}Callback);
|
||||||
|
connect(this, &{{classname}}::abortRequestsSignal, _latestWorker, &QObject::deleteLater);
|
||||||
|
connect(_latestWorker, &QObject::destroyed, [this](){
|
||||||
|
if(findChildren<{{prefix}}HttpRequestWorker*>().count() == 0){
|
||||||
|
emit allPendingRequestsCompleted();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_latestInput = input;
|
||||||
|
_latestScope = scope;{{/isImplicit}}
|
||||||
|
{{#isApplication}}
|
||||||
|
_OauthMethod = 3;
|
||||||
|
_authFlow.unlink();
|
||||||
|
_implicitFlow.unlink();
|
||||||
|
_passwordFlow.unlink();
|
||||||
|
_credentialFlow.link();
|
||||||
|
QStringList scope;
|
||||||
|
{{#scopes}}
|
||||||
|
scope.append("{{scope}}");
|
||||||
|
{{/scopes}}
|
||||||
|
auto token = _credentialFlow.getToken(scope.join(" "));
|
||||||
|
if(token.isValid())
|
||||||
|
input.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
|
||||||
|
_latestWorker = new {{prefix}}HttpRequestWorker(this, _manager);
|
||||||
|
_latestWorker->setTimeOut(_timeOut);
|
||||||
|
_latestWorker->setWorkingDirectory(_workingDirectory);{{#contentCompression}}
|
||||||
|
_latestWorker->setResponseCompressionEnabled(isResponseCompressionEnabled);
|
||||||
|
_latestWorker->setRequestCompressionEnabled(isRequestCompressionEnabled);{{/contentCompression}}
|
||||||
|
|
||||||
|
connect(_latestWorker, &{{prefix}}HttpRequestWorker::on_execution_finished, this, &{{classname}}::{{nickname}}Callback);
|
||||||
|
connect(this, &{{classname}}::abortRequestsSignal, _latestWorker, &QObject::deleteLater);
|
||||||
|
connect(_latestWorker, &QObject::destroyed, [this](){
|
||||||
|
if(findChildren<{{prefix}}HttpRequestWorker*>().count() == 0){
|
||||||
|
emit allPendingRequestsCompleted();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_latestInput = input;
|
||||||
|
_latestScope = scope;{{/isApplication}}
|
||||||
|
{{#isPassword}}
|
||||||
|
_OauthMethod = 4;
|
||||||
|
_passwordFlow.link();
|
||||||
|
_authFlow.unlink();
|
||||||
|
_implicitFlow.unlink();
|
||||||
|
_credentialFlow.unlink();
|
||||||
|
QStringList scope;
|
||||||
|
{{#scopes}}
|
||||||
|
scope.append("{{scope}}");
|
||||||
|
{{/scopes}}
|
||||||
|
auto token = _passwordFlow.getToken(scope.join(" "));
|
||||||
|
if(token.isValid())
|
||||||
|
input.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
|
||||||
|
_latestWorker = new {{prefix}}HttpRequestWorker(this, _manager);
|
||||||
|
_latestWorker->setTimeOut(_timeOut);
|
||||||
|
_latestWorker->setWorkingDirectory(_workingDirectory);{{#contentCompression}}
|
||||||
|
_latestWorker->setResponseCompressionEnabled(isResponseCompressionEnabled);
|
||||||
|
_latestWorker->setRequestCompressionEnabled(isRequestCompressionEnabled);{{/contentCompression}}
|
||||||
|
|
||||||
|
connect(_latestWorker, &{{prefix}}HttpRequestWorker::on_execution_finished, this, &{{classname}}::{{nickname}}Callback);
|
||||||
|
connect(this, &{{classname}}::abortRequestsSignal, _latestWorker, &QObject::deleteLater);
|
||||||
|
connect(_latestWorker, &QObject::destroyed, [this](){
|
||||||
|
if(findChildren<{{prefix}}HttpRequestWorker*>().count() == 0){
|
||||||
|
emit allPendingRequestsCompleted();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_latestInput = input;
|
||||||
|
_latestScope = scope;
|
||||||
|
{{/isPassword}}{{/isOAuth}}{{/authMethods}}
|
||||||
|
|
||||||
worker->execute(&input);
|
worker->execute(&input);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -733,7 +853,56 @@ void {{classname}}::{{nickname}}Callback({{prefix}}HttpRequestWorker *worker) {
|
|||||||
|
|
||||||
if (worker->error_type == QNetworkReply::NoError) {
|
if (worker->error_type == QNetworkReply::NoError) {
|
||||||
emit {{nickname}}Signal({{#returnType}}output{{/returnType}});
|
emit {{nickname}}Signal({{#returnType}}output{{/returnType}});
|
||||||
emit {{nickname}}SignalFull(worker{{#returnType}}, output{{/returnType}});
|
emit {{nickname}}SignalFull(worker{{#returnType}}, output{{/returnType}});{{#authMethods}}{{#isOAuth}}{{#isCode}}
|
||||||
|
} else if(worker->error_type == QNetworkReply::AuthenticationRequiredError){
|
||||||
|
connect(&_authFlow, SIGNAL(tokenReceived()), this, SLOT(tokenAvailable()));
|
||||||
|
QStringList scope;
|
||||||
|
{{#scopes}}
|
||||||
|
scope.append("{{scope}}");
|
||||||
|
{{/scopes}}
|
||||||
|
QString scopeStr = scope.join(" ");
|
||||||
|
QString authorizationUrl("{{authorizationUrl}}");
|
||||||
|
QString tokenUrl("{{tokenUrl}}");
|
||||||
|
//TODO get clientID and Secret and state in the config? https://swagger.io/docs/specification/authentication/oauth2/ states that you should do as you like
|
||||||
|
_authFlow.setVariables(authorizationUrl, tokenUrl, scopeStr, "state" , "http://127.0.0.1:9999", "clientId", "clientSecret");
|
||||||
|
emit _authFlow.authenticationNeeded();{{/isCode}}
|
||||||
|
{{#isImplicit}}
|
||||||
|
} else if(worker->error_type == QNetworkReply::AuthenticationRequiredError){
|
||||||
|
connect(&_implicitFlow, SIGNAL(tokenReceived()), this, SLOT(tokenAvailable()));
|
||||||
|
QStringList scope;
|
||||||
|
{{#scopes}}
|
||||||
|
scope.append("{{scope}}");
|
||||||
|
{{/scopes}}
|
||||||
|
QString scopeStr = scope.join(" ");
|
||||||
|
QString authorizationUrl("{{authorizationUrl}}");
|
||||||
|
//TODO get clientID and Secret and state in the config? https://swagger.io/docs/specification/authentication/oauth2/ states that you should do as you like
|
||||||
|
_implicitFlow.setVariables(authorizationUrl, scopeStr, "state" , "http://127.0.0.1:9999", "clientId");
|
||||||
|
emit _implicitFlow.authenticationNeeded();{{/isImplicit}}
|
||||||
|
{{#isApplication}}
|
||||||
|
} else if(worker->error_type == QNetworkReply::AuthenticationRequiredError){
|
||||||
|
connect(&_credentialFlow, SIGNAL(tokenReceived()), this, SLOT(tokenAvailable()));
|
||||||
|
QStringList scope;
|
||||||
|
{{#scopes}}
|
||||||
|
scope.append("{{scope}}");
|
||||||
|
{{/scopes}}
|
||||||
|
QString scopeStr = scope.join(" ");
|
||||||
|
QString tokenUrl("{{tokenUrl}}");
|
||||||
|
//TODO get clientID and Secret and state in the config? https://swagger.io/docs/specification/authentication/oauth2/ states that you should do as you like
|
||||||
|
_credentialFlow.setVariables(tokenUrl , scopeStr, "clientId", "clientSecret");
|
||||||
|
emit _credentialFlow.authenticationNeeded();{{/isApplication}}
|
||||||
|
{{#isPassword}}
|
||||||
|
} else if(worker->error_type == QNetworkReply::AuthenticationRequiredError){
|
||||||
|
connect(&_passwordFlow, SIGNAL(tokenReceived()), this, SLOT(tokenAvailable()));
|
||||||
|
QStringList scope;
|
||||||
|
{{#scopes}}
|
||||||
|
scope.append("{{scope}}");
|
||||||
|
{{/scopes}}
|
||||||
|
QString scopeStr = scope.join(" ");
|
||||||
|
QString tokenUrl("{{tokenUrl}}");
|
||||||
|
//TODO get clientID and Secret and state in the config? https://swagger.io/docs/specification/authentication/oauth2/ states that you should do as you like
|
||||||
|
_passwordFlow.setVariables(tokenUrl , scopeStr ,"clientId", "clientSecret", "username", "password");
|
||||||
|
emit _passwordFlow.authenticationNeeded();
|
||||||
|
{{/isPassword}}{{/isOAuth}}{{/authMethods}}
|
||||||
} else {
|
} else {
|
||||||
emit {{nickname}}SignalE({{#returnType}}output, {{/returnType}}error_type, error_str);
|
emit {{nickname}}SignalE({{#returnType}}output, {{/returnType}}error_type, error_str);
|
||||||
emit {{nickname}}SignalEFull(worker, error_type, error_str);
|
emit {{nickname}}SignalEFull(worker, error_type, error_str);
|
||||||
@ -742,6 +911,55 @@ void {{classname}}::{{nickname}}Callback({{prefix}}HttpRequestWorker *worker) {
|
|||||||
|
|
||||||
{{/operation}}
|
{{/operation}}
|
||||||
{{/operations}}
|
{{/operations}}
|
||||||
|
void {{classname}}::tokenAvailable(){
|
||||||
|
|
||||||
|
oauthToken token;
|
||||||
|
switch (_OauthMethod) {
|
||||||
|
case 1: //implicit flow
|
||||||
|
token = _implicitFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_implicitFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: //authorization flow
|
||||||
|
token = _authFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_authFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: //client credentials flow
|
||||||
|
token = _credentialFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_credentialFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4: //resource owner password flow
|
||||||
|
token = _passwordFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_credentialFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qDebug() << "No Oauth method set!";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
{{#cppNamespaceDeclarations}}
|
{{#cppNamespaceDeclarations}}
|
||||||
} // namespace {{this}}
|
} // namespace {{this}}
|
||||||
{{/cppNamespaceDeclarations}}
|
{{/cppNamespaceDeclarations}}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "{{prefix}}Helpers.h"
|
#include "{{prefix}}Helpers.h"
|
||||||
#include "{{prefix}}HttpRequest.h"
|
#include "{{prefix}}HttpRequest.h"
|
||||||
#include "{{prefix}}ServerConfiguration.h"
|
#include "{{prefix}}ServerConfiguration.h"
|
||||||
|
#include "{{prefix}}Oauth.h"
|
||||||
|
|
||||||
{{#imports}}{{{import}}}
|
{{#imports}}{{{import}}}
|
||||||
{{/imports}}
|
{{/imports}}
|
||||||
@ -73,6 +74,14 @@ private:
|
|||||||
QMap<QString, QString> _defaultHeaders;
|
QMap<QString, QString> _defaultHeaders;
|
||||||
bool _isResponseCompressionEnabled;
|
bool _isResponseCompressionEnabled;
|
||||||
bool _isRequestCompressionEnabled;
|
bool _isRequestCompressionEnabled;
|
||||||
|
{{prefix}}HttpRequestInput _latestInput;
|
||||||
|
{{prefix}}HttpRequestWorker *_latestWorker;
|
||||||
|
QStringList _latestScope;
|
||||||
|
OauthCode _authFlow;
|
||||||
|
OauthImplicit _implicitFlow;
|
||||||
|
OauthCredentials _credentialFlow;
|
||||||
|
OauthPassword _passwordFlow;
|
||||||
|
int _OauthMethod = 0;
|
||||||
{{#operations}}{{#operation}}
|
{{#operations}}{{#operation}}
|
||||||
void {{nickname}}Callback({{prefix}}HttpRequestWorker *worker);{{/operation}}{{/operations}}
|
void {{nickname}}Callback({{prefix}}HttpRequestWorker *worker);{{/operation}}{{/operations}}
|
||||||
|
|
||||||
@ -88,6 +97,10 @@ signals:
|
|||||||
|
|
||||||
void abortRequestsSignal();
|
void abortRequestsSignal();
|
||||||
void allPendingRequestsCompleted();
|
void allPendingRequestsCompleted();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void tokenAvailable();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
{{#cppNamespaceDeclarations}}
|
{{#cppNamespaceDeclarations}}
|
||||||
|
347
modules/openapi-generator/src/main/resources/cpp-qt-client/oauth.cpp.mustache
vendored
Normal file
347
modules/openapi-generator/src/main/resources/cpp-qt-client/oauth.cpp.mustache
vendored
Normal file
@ -0,0 +1,347 @@
|
|||||||
|
#include "{{prefix}}Oauth.h"
|
||||||
|
|
||||||
|
namespace OpenAPI {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Base class to perform oauth2 flows
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void OauthBase::onFinish(QNetworkReply *rep)
|
||||||
|
{
|
||||||
|
//TODO emit error signal when token is wrong
|
||||||
|
QJsonDocument document = QJsonDocument::fromJson(rep->readAll());
|
||||||
|
QJsonObject rootObj = document.object();
|
||||||
|
QString token = rootObj.find("access_token").value().toString();
|
||||||
|
QString scope = rootObj.find("scope").value().toString();
|
||||||
|
QString type = rootObj.find("token_type").value().toString();
|
||||||
|
int expiresIn = rootObj.find("expires_in").value().toInt();
|
||||||
|
addToken(oauthToken(token, expiresIn, scope, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
oauthToken OauthBase::getToken(QString scope)
|
||||||
|
{
|
||||||
|
auto tokenIt = m_oauthTokenMap.find(scope);
|
||||||
|
return tokenIt != m_oauthTokenMap.end() ? tokenIt.value() : oauthToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthBase::addToken(oauthToken token)
|
||||||
|
{
|
||||||
|
m_oauthTokenMap.insert(token.getScope(),token);
|
||||||
|
emit tokenReceived();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthBase::removeToken(QString scope)
|
||||||
|
{
|
||||||
|
m_oauthTokenMap.remove(scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class to perform the authorization code flow
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
OauthCode::OauthCode(QObject *parent) : OauthBase(parent){}
|
||||||
|
|
||||||
|
void OauthCode::link(){
|
||||||
|
connect(&m_server, SIGNAL(dataReceived(QMap<QString,QString>)), this, SLOT(onVerificationReceived(QMap<QString,QString>)));
|
||||||
|
connect(this, SIGNAL(authenticationNeeded()), this, SLOT(authenticationNeededCallback()));
|
||||||
|
connect(this, SIGNAL(tokenReceived()), &m_server, SLOT(stop()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthCode::unlink()
|
||||||
|
{
|
||||||
|
disconnect(this,0,0,0);
|
||||||
|
disconnect(&m_server,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthCode::setVariables(QString authUrl, QString tokenUrl, QString scope, QString state, QString redirectUri, QString clientId, QString clientSecret, QString accessType){
|
||||||
|
|
||||||
|
m_authUrl = QUrl(authUrl);
|
||||||
|
m_tokenUrl = QUrl(tokenUrl);
|
||||||
|
m_scope = scope;
|
||||||
|
m_accessType = accessType;
|
||||||
|
m_state = state;
|
||||||
|
m_redirectUri = redirectUri;
|
||||||
|
m_clientId = clientId;
|
||||||
|
m_clientSecret = clientSecret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthCode::authenticationNeededCallback()
|
||||||
|
{
|
||||||
|
QDesktopServices::openUrl(QUrl(m_authUrl.toString() + "?scope=" + m_scope + (m_accessType=="" ? "" : "&access_type=" + m_accessType) + "&response_type=code" + "&state=" + m_state + "&redirect_uri=" + m_redirectUri + "&client_id=" + m_clientId));
|
||||||
|
m_server.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthCode::onVerificationReceived(const QMap<QString, QString> response) {
|
||||||
|
|
||||||
|
// Save access code
|
||||||
|
QString state(response.value("state"));
|
||||||
|
QString scope(response.value("scope"));
|
||||||
|
QString code(response.value("code"));
|
||||||
|
|
||||||
|
//create query with the required fields
|
||||||
|
QUrlQuery postData;
|
||||||
|
postData.addQueryItem("grant_type", "authorization_code");
|
||||||
|
postData.addQueryItem("client_id", m_clientId);
|
||||||
|
postData.addQueryItem("client_secret", m_clientSecret);
|
||||||
|
postData.addQueryItem("code", code);
|
||||||
|
postData.addQueryItem("redirect_uri", m_redirectUri);
|
||||||
|
QNetworkAccessManager * manager = new QNetworkAccessManager(this);
|
||||||
|
|
||||||
|
QNetworkRequest request(m_tokenUrl);
|
||||||
|
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(onFinish(QNetworkReply *)));
|
||||||
|
|
||||||
|
manager->post(request, postData.query().toUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class to perform the implicit flow
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
OauthImplicit::OauthImplicit(QObject *parent) : OauthBase(parent){}
|
||||||
|
|
||||||
|
void OauthImplicit::link()
|
||||||
|
{
|
||||||
|
//TODO correct linking
|
||||||
|
connect(&m_server, SIGNAL(dataReceived(QMap<QString,QString>)), this, SLOT(ImplicitTokenReceived(QMap<QString,QString>)));
|
||||||
|
connect(this, SIGNAL(authenticationNeeded()), this, SLOT(authenticationNeededCallback()));
|
||||||
|
connect(this, SIGNAL(tokenReceived()), &m_server, SLOT(stop()));
|
||||||
|
m_linked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthImplicit::unlink()
|
||||||
|
{
|
||||||
|
disconnect(this,0,0,0);
|
||||||
|
disconnect(&m_server,0,0,0);
|
||||||
|
m_linked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthImplicit::setVariables(QString authUrl, QString scope, QString state, QString redirectUri, QString clientId, QString accessType){
|
||||||
|
|
||||||
|
m_authUrl = QUrl(authUrl);
|
||||||
|
m_scope = scope;
|
||||||
|
m_accessType = accessType;
|
||||||
|
m_state = state;
|
||||||
|
m_redirectUri = redirectUri;
|
||||||
|
m_clientId = clientId;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthImplicit::authenticationNeededCallback()
|
||||||
|
{
|
||||||
|
QDesktopServices::openUrl(QUrl(m_authUrl.toString() + "?scope=" + m_scope + (m_accessType=="" ? "" : "&access_type=" + m_accessType) + "&response_type=token" + "&state=" + m_state + "&redirect_uri=" + m_redirectUri + "&client_id=" + m_clientId));
|
||||||
|
m_server.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthImplicit::ImplicitTokenReceived(const QMap<QString, QString> response)
|
||||||
|
{
|
||||||
|
QString token = response.find("access_token").value();
|
||||||
|
QString scope = response.find("scope").value();
|
||||||
|
QString type = response.find("token_type").value();
|
||||||
|
int expiresIn = response.find("expires_in").value().toInt();
|
||||||
|
addToken(oauthToken(token, expiresIn, scope, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class to perform the client credentials flow
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
OauthCredentials::OauthCredentials(QObject *parent) : OauthBase(parent){}
|
||||||
|
void OauthCredentials::link()
|
||||||
|
{
|
||||||
|
connect(this, SIGNAL(authenticationNeeded()), this, SLOT(authenticationNeededCallback()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthCredentials::unlink()
|
||||||
|
{
|
||||||
|
disconnect(this,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthCredentials::setVariables(QString tokenUrl, QString scope, QString clientId, QString clientSecret){
|
||||||
|
|
||||||
|
m_tokenUrl = QUrl(tokenUrl);
|
||||||
|
m_scope = scope;
|
||||||
|
m_clientId = clientId;
|
||||||
|
m_clientSecret = clientSecret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthCredentials::authenticationNeededCallback()
|
||||||
|
{
|
||||||
|
//create query with the required fields
|
||||||
|
QUrlQuery postData;
|
||||||
|
postData.addQueryItem("grant_type", "client_credentials");
|
||||||
|
postData.addQueryItem("client_id", m_clientId);
|
||||||
|
postData.addQueryItem("client_secret", m_clientSecret);
|
||||||
|
postData.addQueryItem("scope", m_scope);
|
||||||
|
QNetworkAccessManager * manager = new QNetworkAccessManager(this);
|
||||||
|
|
||||||
|
QNetworkRequest request(m_tokenUrl);
|
||||||
|
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(onFinish(QNetworkReply *)));
|
||||||
|
|
||||||
|
manager->post(request, postData.query().toUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class to perform the resource owner password flow
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
OauthPassword::OauthPassword(QObject *parent) : OauthBase(parent){}
|
||||||
|
void OauthPassword::link()
|
||||||
|
{
|
||||||
|
connect(this, SIGNAL(authenticationNeeded()), this, SLOT(authenticationNeededCallback()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthPassword::unlink()
|
||||||
|
{
|
||||||
|
disconnect(this,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthPassword::setVariables(QString tokenUrl, QString scope, QString clientId, QString clientSecret, QString username, QString password){
|
||||||
|
|
||||||
|
m_tokenUrl = QUrl(tokenUrl);
|
||||||
|
m_scope = scope;
|
||||||
|
m_clientId = clientId;
|
||||||
|
m_clientSecret = clientSecret;
|
||||||
|
m_username = username;
|
||||||
|
m_password = password;
|
||||||
|
|
||||||
|
}
|
||||||
|
void OauthPassword::authenticationNeededCallback()
|
||||||
|
{
|
||||||
|
//create query with the required fields
|
||||||
|
QUrlQuery postData;
|
||||||
|
postData.addQueryItem("grant_type", "password");
|
||||||
|
postData.addQueryItem("username", m_username);
|
||||||
|
postData.addQueryItem("password", m_password);
|
||||||
|
postData.addQueryItem("client_id", m_clientId);
|
||||||
|
postData.addQueryItem("client_secret", m_clientSecret);
|
||||||
|
postData.addQueryItem("scope", m_scope);
|
||||||
|
QNetworkAccessManager * manager = new QNetworkAccessManager(this);
|
||||||
|
|
||||||
|
QNetworkRequest request(m_tokenUrl);
|
||||||
|
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(onFinish(QNetworkReply *)));
|
||||||
|
|
||||||
|
manager->post(request, postData.query().toUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class that provides a simple reply server
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
ReplyServer::ReplyServer(QObject *parent) : QTcpServer(parent)
|
||||||
|
{
|
||||||
|
connect(this, SIGNAL(newConnection()), this, SLOT(onConnected()));
|
||||||
|
m_reply ="you can close this window now!";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReplyServer::start()
|
||||||
|
{
|
||||||
|
if(!listen(QHostAddress::Any, 9999))
|
||||||
|
{
|
||||||
|
qDebug() << "Server could not start";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << "Server started!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReplyServer::stop()
|
||||||
|
{
|
||||||
|
qDebug() << "Stopping the Server...";
|
||||||
|
QTcpServer::close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReplyServer::onConnected()
|
||||||
|
{
|
||||||
|
// need to grab the socket
|
||||||
|
QTcpSocket *socket = nextPendingConnection();
|
||||||
|
connect(socket, SIGNAL(readyRead()), this, SLOT(read()), Qt::UniqueConnection);
|
||||||
|
connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReplyServer::read()
|
||||||
|
{
|
||||||
|
QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
|
||||||
|
if (!socket) {
|
||||||
|
qDebug() << "No socket available";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qDebug() << "Socket connected";
|
||||||
|
|
||||||
|
QTextStream os(socket);
|
||||||
|
os.setAutoDetectUnicode(true);
|
||||||
|
os << "HTTP/1.0 200 Ok\r\n"
|
||||||
|
"Content-Type: text/html; charset=\"utf-8\"\r\n"
|
||||||
|
"\r\n"
|
||||||
|
<<"<!DOCTYPE html>\
|
||||||
|
<html>\
|
||||||
|
<head>\
|
||||||
|
<script>\
|
||||||
|
window.onload = function hashFunction() {\
|
||||||
|
var query = location.hash.substr(1);\
|
||||||
|
if (query != \"\") {\
|
||||||
|
var xhttp = new XMLHttpRequest();\
|
||||||
|
xhttp.open(\"GET\", \"/?\" + query, true);\
|
||||||
|
xhttp.send();\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
</script>\
|
||||||
|
</head>\
|
||||||
|
<body>\
|
||||||
|
<h2>You can close this window now!</h2>\
|
||||||
|
</body>\
|
||||||
|
</html>";
|
||||||
|
|
||||||
|
QByteArray data = socket->readLine();
|
||||||
|
QString splitGetLine = QString(data);
|
||||||
|
splitGetLine.remove("GET");
|
||||||
|
splitGetLine.remove("HTTP/1.1");
|
||||||
|
splitGetLine.remove("\r\n");
|
||||||
|
splitGetLine.remove(" ");
|
||||||
|
//prefix is needed to extract query params
|
||||||
|
QUrl getTokenUrl("http://" + splitGetLine);
|
||||||
|
QList< QPair<QString, QString> > tokens;
|
||||||
|
|
||||||
|
QUrlQuery query(getTokenUrl);
|
||||||
|
tokens = query.queryItems();
|
||||||
|
|
||||||
|
|
||||||
|
QMap<QString, QString> queryParams;
|
||||||
|
QPair<QString, QString> tokenPair;
|
||||||
|
foreach (tokenPair, tokens) {
|
||||||
|
QString key = QUrl::fromPercentEncoding(QByteArray().append(tokenPair.first.trimmed().toLatin1()));
|
||||||
|
QString value = QUrl::fromPercentEncoding(QByteArray().append(tokenPair.second.trimmed().toLatin1()));
|
||||||
|
queryParams.insert(key, value);
|
||||||
|
}
|
||||||
|
if (!queryParams.contains("state")) {
|
||||||
|
|
||||||
|
socket->close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
socket->close();
|
||||||
|
|
||||||
|
emit dataReceived(queryParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
175
modules/openapi-generator/src/main/resources/cpp-qt-client/oauth.h.mustache
vendored
Normal file
175
modules/openapi-generator/src/main/resources/cpp-qt-client/oauth.h.mustache
vendored
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
{{>licenseInfo}}
|
||||||
|
/**
|
||||||
|
* Providing a Oauth2 Class and a ReplyServer for the Oauth2 authorization code flow.
|
||||||
|
*/
|
||||||
|
#ifndef {{prefix}}_OAUTH2_H
|
||||||
|
#define {{prefix}}_OAUTH2_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QtCore>
|
||||||
|
#include <QtNetwork>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QtDebug>
|
||||||
|
#include <QTcpServer>
|
||||||
|
#include <QTcpSocket>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QString>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QUrlQuery>
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{{#cppNamespaceDeclarations}}
|
||||||
|
namespace {{this}} {
|
||||||
|
{{/cppNamespaceDeclarations}}
|
||||||
|
|
||||||
|
class oauthToken
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
oauthToken(QString token, int expiresIn, QString scope, QString tokenType) : m_token(token), m_scope(scope), m_type(tokenType){
|
||||||
|
m_validUntil = QDateTime::fromSecsSinceEpoch(QDateTime::currentSecsSinceEpoch() + expiresIn);
|
||||||
|
}
|
||||||
|
oauthToken(){
|
||||||
|
m_validUntil = QDateTime::fromSecsSinceEpoch(QDateTime::currentSecsSinceEpoch() -1);
|
||||||
|
}
|
||||||
|
QString getToken(){return m_token;};
|
||||||
|
QString getScope(){return m_scope;};
|
||||||
|
QString getType(){return m_type;};
|
||||||
|
bool isValid(){return QDateTime::currentDateTime() < m_validUntil;};
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_token;
|
||||||
|
QDateTime m_validUntil;
|
||||||
|
QString m_scope;
|
||||||
|
QString m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReplyServer : public QTcpServer
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ReplyServer(QObject *parent = nullptr);
|
||||||
|
void setReply(QByteArray reply){m_reply = reply;};
|
||||||
|
void run();
|
||||||
|
private:
|
||||||
|
QByteArray m_reply;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void dataReceived(QMap<QString, QString>);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void onConnected();
|
||||||
|
void read();
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
};
|
||||||
|
|
||||||
|
//Base class
|
||||||
|
class OauthBase : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
OauthBase(QObject* parent = nullptr) : QObject(parent) {};
|
||||||
|
oauthToken getToken(QString scope);
|
||||||
|
void addToken(oauthToken token);
|
||||||
|
void removeToken(QString scope);
|
||||||
|
bool linked(){return m_linked;};
|
||||||
|
virtual void link()=0;
|
||||||
|
virtual void unlink()=0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QMap<QString, oauthToken> m_oauthTokenMap;
|
||||||
|
QUrl m_authUrl;
|
||||||
|
QUrl m_tokenUrl;
|
||||||
|
QString m_scope, m_accessType, m_state, m_redirectUri, m_clientId, m_clientSecret;
|
||||||
|
bool m_linked;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void authenticationNeededCallback()=0;
|
||||||
|
void onFinish(QNetworkReply *rep);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void authenticationNeeded();
|
||||||
|
void tokenReceived();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Authorization code flow
|
||||||
|
class OauthCode : public OauthBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
OauthCode(QObject *parent = nullptr);
|
||||||
|
void link() override;
|
||||||
|
void unlink() override;
|
||||||
|
void setVariables(QString authUrl, QString tokenUrl, QString scope, QString state, QString redirectUri, QString clientId, QString clientSecret, QString accessType = "");
|
||||||
|
|
||||||
|
private:
|
||||||
|
ReplyServer m_server;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void authenticationNeededCallback() override;
|
||||||
|
void onVerificationReceived(const QMap<QString, QString> response);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implicit flow
|
||||||
|
class OauthImplicit : public OauthBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
OauthImplicit(QObject *parent = nullptr);
|
||||||
|
void link() override;
|
||||||
|
void unlink() override;
|
||||||
|
void setVariables(QString authUrl, QString scope, QString state, QString redirectUri, QString clientId, QString accessType = "");
|
||||||
|
|
||||||
|
private:
|
||||||
|
ReplyServer m_server;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void authenticationNeededCallback() override;
|
||||||
|
void ImplicitTokenReceived(const QMap<QString, QString> response);
|
||||||
|
};
|
||||||
|
|
||||||
|
//client credentials flow
|
||||||
|
class OauthCredentials : public OauthBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
OauthCredentials(QObject *parent = nullptr);
|
||||||
|
void link() override;
|
||||||
|
void unlink() override;
|
||||||
|
void setVariables(QString tokenUrl, QString scope, QString clientId, QString clientSecret);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void authenticationNeededCallback() override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//resource owner password flow
|
||||||
|
class OauthPassword : public OauthBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
OauthPassword(QObject *parent = nullptr);
|
||||||
|
void link() override;
|
||||||
|
void unlink() override;
|
||||||
|
void setVariables(QString tokenUrl, QString scope, QString clientId, QString clientSecret, QString username, QString password);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_username, m_password;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void authenticationNeededCallback() override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
{{#cppNamespaceDeclarations}}
|
||||||
|
} // namespace {{this}}
|
||||||
|
{{/cppNamespaceDeclarations}}
|
||||||
|
#endif // {{prefix}}_OAUTH2_H
|
@ -11,6 +11,8 @@ client/PFXHttpFileElement.cpp
|
|||||||
client/PFXHttpFileElement.h
|
client/PFXHttpFileElement.h
|
||||||
client/PFXHttpRequest.cpp
|
client/PFXHttpRequest.cpp
|
||||||
client/PFXHttpRequest.h
|
client/PFXHttpRequest.h
|
||||||
|
client/PFXOauth.cpp
|
||||||
|
client/PFXOauth.h
|
||||||
client/PFXObject.h
|
client/PFXObject.h
|
||||||
client/PFXOrder.cpp
|
client/PFXOrder.cpp
|
||||||
client/PFXOrder.h
|
client/PFXOrder.h
|
||||||
|
347
samples/client/petstore/cpp-qt/client/PFXOauth.cpp
Normal file
347
samples/client/petstore/cpp-qt/client/PFXOauth.cpp
Normal file
@ -0,0 +1,347 @@
|
|||||||
|
#include "PFXOauth.h"
|
||||||
|
|
||||||
|
namespace OpenAPI {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Base class to perform oauth2 flows
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void OauthBase::onFinish(QNetworkReply *rep)
|
||||||
|
{
|
||||||
|
//TODO emit error signal when token is wrong
|
||||||
|
QJsonDocument document = QJsonDocument::fromJson(rep->readAll());
|
||||||
|
QJsonObject rootObj = document.object();
|
||||||
|
QString token = rootObj.find("access_token").value().toString();
|
||||||
|
QString scope = rootObj.find("scope").value().toString();
|
||||||
|
QString type = rootObj.find("token_type").value().toString();
|
||||||
|
int expiresIn = rootObj.find("expires_in").value().toInt();
|
||||||
|
addToken(oauthToken(token, expiresIn, scope, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
oauthToken OauthBase::getToken(QString scope)
|
||||||
|
{
|
||||||
|
auto tokenIt = m_oauthTokenMap.find(scope);
|
||||||
|
return tokenIt != m_oauthTokenMap.end() ? tokenIt.value() : oauthToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthBase::addToken(oauthToken token)
|
||||||
|
{
|
||||||
|
m_oauthTokenMap.insert(token.getScope(),token);
|
||||||
|
emit tokenReceived();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthBase::removeToken(QString scope)
|
||||||
|
{
|
||||||
|
m_oauthTokenMap.remove(scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class to perform the authorization code flow
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
OauthCode::OauthCode(QObject *parent) : OauthBase(parent){}
|
||||||
|
|
||||||
|
void OauthCode::link(){
|
||||||
|
connect(&m_server, SIGNAL(dataReceived(QMap<QString,QString>)), this, SLOT(onVerificationReceived(QMap<QString,QString>)));
|
||||||
|
connect(this, SIGNAL(authenticationNeeded()), this, SLOT(authenticationNeededCallback()));
|
||||||
|
connect(this, SIGNAL(tokenReceived()), &m_server, SLOT(stop()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthCode::unlink()
|
||||||
|
{
|
||||||
|
disconnect(this,0,0,0);
|
||||||
|
disconnect(&m_server,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthCode::setVariables(QString authUrl, QString tokenUrl, QString scope, QString state, QString redirectUri, QString clientId, QString clientSecret, QString accessType){
|
||||||
|
|
||||||
|
m_authUrl = QUrl(authUrl);
|
||||||
|
m_tokenUrl = QUrl(tokenUrl);
|
||||||
|
m_scope = scope;
|
||||||
|
m_accessType = accessType;
|
||||||
|
m_state = state;
|
||||||
|
m_redirectUri = redirectUri;
|
||||||
|
m_clientId = clientId;
|
||||||
|
m_clientSecret = clientSecret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthCode::authenticationNeededCallback()
|
||||||
|
{
|
||||||
|
QDesktopServices::openUrl(QUrl(m_authUrl.toString() + "?scope=" + m_scope + (m_accessType=="" ? "" : "&access_type=" + m_accessType) + "&response_type=code" + "&state=" + m_state + "&redirect_uri=" + m_redirectUri + "&client_id=" + m_clientId));
|
||||||
|
m_server.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthCode::onVerificationReceived(const QMap<QString, QString> response) {
|
||||||
|
|
||||||
|
// Save access code
|
||||||
|
QString state(response.value("state"));
|
||||||
|
QString scope(response.value("scope"));
|
||||||
|
QString code(response.value("code"));
|
||||||
|
|
||||||
|
//create query with the required fields
|
||||||
|
QUrlQuery postData;
|
||||||
|
postData.addQueryItem("grant_type", "authorization_code");
|
||||||
|
postData.addQueryItem("client_id", m_clientId);
|
||||||
|
postData.addQueryItem("client_secret", m_clientSecret);
|
||||||
|
postData.addQueryItem("code", code);
|
||||||
|
postData.addQueryItem("redirect_uri", m_redirectUri);
|
||||||
|
QNetworkAccessManager * manager = new QNetworkAccessManager(this);
|
||||||
|
|
||||||
|
QNetworkRequest request(m_tokenUrl);
|
||||||
|
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(onFinish(QNetworkReply *)));
|
||||||
|
|
||||||
|
manager->post(request, postData.query().toUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class to perform the implicit flow
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
OauthImplicit::OauthImplicit(QObject *parent) : OauthBase(parent){}
|
||||||
|
|
||||||
|
void OauthImplicit::link()
|
||||||
|
{
|
||||||
|
//TODO correct linking
|
||||||
|
connect(&m_server, SIGNAL(dataReceived(QMap<QString,QString>)), this, SLOT(ImplicitTokenReceived(QMap<QString,QString>)));
|
||||||
|
connect(this, SIGNAL(authenticationNeeded()), this, SLOT(authenticationNeededCallback()));
|
||||||
|
connect(this, SIGNAL(tokenReceived()), &m_server, SLOT(stop()));
|
||||||
|
m_linked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthImplicit::unlink()
|
||||||
|
{
|
||||||
|
disconnect(this,0,0,0);
|
||||||
|
disconnect(&m_server,0,0,0);
|
||||||
|
m_linked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthImplicit::setVariables(QString authUrl, QString scope, QString state, QString redirectUri, QString clientId, QString accessType){
|
||||||
|
|
||||||
|
m_authUrl = QUrl(authUrl);
|
||||||
|
m_scope = scope;
|
||||||
|
m_accessType = accessType;
|
||||||
|
m_state = state;
|
||||||
|
m_redirectUri = redirectUri;
|
||||||
|
m_clientId = clientId;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthImplicit::authenticationNeededCallback()
|
||||||
|
{
|
||||||
|
QDesktopServices::openUrl(QUrl(m_authUrl.toString() + "?scope=" + m_scope + (m_accessType=="" ? "" : "&access_type=" + m_accessType) + "&response_type=token" + "&state=" + m_state + "&redirect_uri=" + m_redirectUri + "&client_id=" + m_clientId));
|
||||||
|
m_server.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthImplicit::ImplicitTokenReceived(const QMap<QString, QString> response)
|
||||||
|
{
|
||||||
|
QString token = response.find("access_token").value();
|
||||||
|
QString scope = response.find("scope").value();
|
||||||
|
QString type = response.find("token_type").value();
|
||||||
|
int expiresIn = response.find("expires_in").value().toInt();
|
||||||
|
addToken(oauthToken(token, expiresIn, scope, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class to perform the client credentials flow
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
OauthCredentials::OauthCredentials(QObject *parent) : OauthBase(parent){}
|
||||||
|
void OauthCredentials::link()
|
||||||
|
{
|
||||||
|
connect(this, SIGNAL(authenticationNeeded()), this, SLOT(authenticationNeededCallback()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthCredentials::unlink()
|
||||||
|
{
|
||||||
|
disconnect(this,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthCredentials::setVariables(QString tokenUrl, QString scope, QString clientId, QString clientSecret){
|
||||||
|
|
||||||
|
m_tokenUrl = QUrl(tokenUrl);
|
||||||
|
m_scope = scope;
|
||||||
|
m_clientId = clientId;
|
||||||
|
m_clientSecret = clientSecret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthCredentials::authenticationNeededCallback()
|
||||||
|
{
|
||||||
|
//create query with the required fields
|
||||||
|
QUrlQuery postData;
|
||||||
|
postData.addQueryItem("grant_type", "client_credentials");
|
||||||
|
postData.addQueryItem("client_id", m_clientId);
|
||||||
|
postData.addQueryItem("client_secret", m_clientSecret);
|
||||||
|
postData.addQueryItem("scope", m_scope);
|
||||||
|
QNetworkAccessManager * manager = new QNetworkAccessManager(this);
|
||||||
|
|
||||||
|
QNetworkRequest request(m_tokenUrl);
|
||||||
|
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(onFinish(QNetworkReply *)));
|
||||||
|
|
||||||
|
manager->post(request, postData.query().toUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class to perform the resource owner password flow
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
OauthPassword::OauthPassword(QObject *parent) : OauthBase(parent){}
|
||||||
|
void OauthPassword::link()
|
||||||
|
{
|
||||||
|
connect(this, SIGNAL(authenticationNeeded()), this, SLOT(authenticationNeededCallback()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthPassword::unlink()
|
||||||
|
{
|
||||||
|
disconnect(this,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OauthPassword::setVariables(QString tokenUrl, QString scope, QString clientId, QString clientSecret, QString username, QString password){
|
||||||
|
|
||||||
|
m_tokenUrl = QUrl(tokenUrl);
|
||||||
|
m_scope = scope;
|
||||||
|
m_clientId = clientId;
|
||||||
|
m_clientSecret = clientSecret;
|
||||||
|
m_username = username;
|
||||||
|
m_password = password;
|
||||||
|
|
||||||
|
}
|
||||||
|
void OauthPassword::authenticationNeededCallback()
|
||||||
|
{
|
||||||
|
//create query with the required fields
|
||||||
|
QUrlQuery postData;
|
||||||
|
postData.addQueryItem("grant_type", "password");
|
||||||
|
postData.addQueryItem("username", m_username);
|
||||||
|
postData.addQueryItem("password", m_password);
|
||||||
|
postData.addQueryItem("client_id", m_clientId);
|
||||||
|
postData.addQueryItem("client_secret", m_clientSecret);
|
||||||
|
postData.addQueryItem("scope", m_scope);
|
||||||
|
QNetworkAccessManager * manager = new QNetworkAccessManager(this);
|
||||||
|
|
||||||
|
QNetworkRequest request(m_tokenUrl);
|
||||||
|
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(onFinish(QNetworkReply *)));
|
||||||
|
|
||||||
|
manager->post(request, postData.query().toUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class that provides a simple reply server
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
ReplyServer::ReplyServer(QObject *parent) : QTcpServer(parent)
|
||||||
|
{
|
||||||
|
connect(this, SIGNAL(newConnection()), this, SLOT(onConnected()));
|
||||||
|
m_reply ="you can close this window now!";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReplyServer::start()
|
||||||
|
{
|
||||||
|
if(!listen(QHostAddress::Any, 9999))
|
||||||
|
{
|
||||||
|
qDebug() << "Server could not start";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << "Server started!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReplyServer::stop()
|
||||||
|
{
|
||||||
|
qDebug() << "Stopping the Server...";
|
||||||
|
QTcpServer::close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReplyServer::onConnected()
|
||||||
|
{
|
||||||
|
// need to grab the socket
|
||||||
|
QTcpSocket *socket = nextPendingConnection();
|
||||||
|
connect(socket, SIGNAL(readyRead()), this, SLOT(read()), Qt::UniqueConnection);
|
||||||
|
connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReplyServer::read()
|
||||||
|
{
|
||||||
|
QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
|
||||||
|
if (!socket) {
|
||||||
|
qDebug() << "No socket available";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qDebug() << "Socket connected";
|
||||||
|
|
||||||
|
QTextStream os(socket);
|
||||||
|
os.setAutoDetectUnicode(true);
|
||||||
|
os << "HTTP/1.0 200 Ok\r\n"
|
||||||
|
"Content-Type: text/html; charset=\"utf-8\"\r\n"
|
||||||
|
"\r\n"
|
||||||
|
<<"<!DOCTYPE html>\
|
||||||
|
<html>\
|
||||||
|
<head>\
|
||||||
|
<script>\
|
||||||
|
window.onload = function hashFunction() {\
|
||||||
|
var query = location.hash.substr(1);\
|
||||||
|
if (query != \"\") {\
|
||||||
|
var xhttp = new XMLHttpRequest();\
|
||||||
|
xhttp.open(\"GET\", \"/?\" + query, true);\
|
||||||
|
xhttp.send();\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
</script>\
|
||||||
|
</head>\
|
||||||
|
<body>\
|
||||||
|
<h2>You can close this window now!</h2>\
|
||||||
|
</body>\
|
||||||
|
</html>";
|
||||||
|
|
||||||
|
QByteArray data = socket->readLine();
|
||||||
|
QString splitGetLine = QString(data);
|
||||||
|
splitGetLine.remove("GET");
|
||||||
|
splitGetLine.remove("HTTP/1.1");
|
||||||
|
splitGetLine.remove("\r\n");
|
||||||
|
splitGetLine.remove(" ");
|
||||||
|
//prefix is needed to extract query params
|
||||||
|
QUrl getTokenUrl("http://" + splitGetLine);
|
||||||
|
QList< QPair<QString, QString> > tokens;
|
||||||
|
|
||||||
|
QUrlQuery query(getTokenUrl);
|
||||||
|
tokens = query.queryItems();
|
||||||
|
|
||||||
|
|
||||||
|
QMap<QString, QString> queryParams;
|
||||||
|
QPair<QString, QString> tokenPair;
|
||||||
|
foreach (tokenPair, tokens) {
|
||||||
|
QString key = QUrl::fromPercentEncoding(QByteArray().append(tokenPair.first.trimmed().toLatin1()));
|
||||||
|
QString value = QUrl::fromPercentEncoding(QByteArray().append(tokenPair.second.trimmed().toLatin1()));
|
||||||
|
queryParams.insert(key, value);
|
||||||
|
}
|
||||||
|
if (!queryParams.contains("state")) {
|
||||||
|
|
||||||
|
socket->close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
socket->close();
|
||||||
|
|
||||||
|
emit dataReceived(queryParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
181
samples/client/petstore/cpp-qt/client/PFXOauth.h
Normal file
181
samples/client/petstore/cpp-qt/client/PFXOauth.h
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
/**
|
||||||
|
* OpenAPI Petstore
|
||||||
|
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 1.0.0
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Providing a Oauth2 Class and a ReplyServer for the Oauth2 authorization code flow.
|
||||||
|
*/
|
||||||
|
#ifndef PFX_OAUTH2_H
|
||||||
|
#define PFX_OAUTH2_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QtCore>
|
||||||
|
#include <QtNetwork>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QtDebug>
|
||||||
|
#include <QTcpServer>
|
||||||
|
#include <QTcpSocket>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QString>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QUrlQuery>
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace test_namespace {
|
||||||
|
|
||||||
|
class oauthToken
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
oauthToken(QString token, int expiresIn, QString scope, QString tokenType) : m_token(token), m_scope(scope), m_type(tokenType){
|
||||||
|
m_validUntil = QDateTime::fromSecsSinceEpoch(QDateTime::currentSecsSinceEpoch() + expiresIn);
|
||||||
|
}
|
||||||
|
oauthToken(){
|
||||||
|
m_validUntil = QDateTime::fromSecsSinceEpoch(QDateTime::currentSecsSinceEpoch() -1);
|
||||||
|
}
|
||||||
|
QString getToken(){return m_token;};
|
||||||
|
QString getScope(){return m_scope;};
|
||||||
|
QString getType(){return m_type;};
|
||||||
|
bool isValid(){return QDateTime::currentDateTime() < m_validUntil;};
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_token;
|
||||||
|
QDateTime m_validUntil;
|
||||||
|
QString m_scope;
|
||||||
|
QString m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReplyServer : public QTcpServer
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ReplyServer(QObject *parent = nullptr);
|
||||||
|
void setReply(QByteArray reply){m_reply = reply;};
|
||||||
|
void run();
|
||||||
|
private:
|
||||||
|
QByteArray m_reply;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void dataReceived(QMap<QString, QString>);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void onConnected();
|
||||||
|
void read();
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
};
|
||||||
|
|
||||||
|
//Base class
|
||||||
|
class OauthBase : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
OauthBase(QObject* parent = nullptr) : QObject(parent) {};
|
||||||
|
oauthToken getToken(QString scope);
|
||||||
|
void addToken(oauthToken token);
|
||||||
|
void removeToken(QString scope);
|
||||||
|
bool linked(){return m_linked;};
|
||||||
|
virtual void link()=0;
|
||||||
|
virtual void unlink()=0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QMap<QString, oauthToken> m_oauthTokenMap;
|
||||||
|
QUrl m_authUrl;
|
||||||
|
QUrl m_tokenUrl;
|
||||||
|
QString m_scope, m_accessType, m_state, m_redirectUri, m_clientId, m_clientSecret;
|
||||||
|
bool m_linked;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void authenticationNeededCallback()=0;
|
||||||
|
void onFinish(QNetworkReply *rep);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void authenticationNeeded();
|
||||||
|
void tokenReceived();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Authorization code flow
|
||||||
|
class OauthCode : public OauthBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
OauthCode(QObject *parent = nullptr);
|
||||||
|
void link() override;
|
||||||
|
void unlink() override;
|
||||||
|
void setVariables(QString authUrl, QString tokenUrl, QString scope, QString state, QString redirectUri, QString clientId, QString clientSecret, QString accessType = "");
|
||||||
|
|
||||||
|
private:
|
||||||
|
ReplyServer m_server;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void authenticationNeededCallback() override;
|
||||||
|
void onVerificationReceived(const QMap<QString, QString> response);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implicit flow
|
||||||
|
class OauthImplicit : public OauthBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
OauthImplicit(QObject *parent = nullptr);
|
||||||
|
void link() override;
|
||||||
|
void unlink() override;
|
||||||
|
void setVariables(QString authUrl, QString scope, QString state, QString redirectUri, QString clientId, QString accessType = "");
|
||||||
|
|
||||||
|
private:
|
||||||
|
ReplyServer m_server;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void authenticationNeededCallback() override;
|
||||||
|
void ImplicitTokenReceived(const QMap<QString, QString> response);
|
||||||
|
};
|
||||||
|
|
||||||
|
//client credentials flow
|
||||||
|
class OauthCredentials : public OauthBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
OauthCredentials(QObject *parent = nullptr);
|
||||||
|
void link() override;
|
||||||
|
void unlink() override;
|
||||||
|
void setVariables(QString tokenUrl, QString scope, QString clientId, QString clientSecret);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void authenticationNeededCallback() override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//resource owner password flow
|
||||||
|
class OauthPassword : public OauthBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
OauthPassword(QObject *parent = nullptr);
|
||||||
|
void link() override;
|
||||||
|
void unlink() override;
|
||||||
|
void setVariables(QString tokenUrl, QString scope, QString clientId, QString clientSecret, QString username, QString password);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_username, m_password;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void authenticationNeededCallback() override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace test_namespace
|
||||||
|
#endif // PFX_OAUTH2_H
|
@ -256,6 +256,34 @@ void PFXPetApi::addPet(const PFXPet &body) {
|
|||||||
emit allPendingRequestsCompleted();
|
emit allPendingRequestsCompleted();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
_OauthMethod = 1;
|
||||||
|
_implicitFlow.link();
|
||||||
|
_passwordFlow.unlink();
|
||||||
|
_authFlow.unlink();
|
||||||
|
_credentialFlow.unlink();
|
||||||
|
QStringList scope;
|
||||||
|
scope.append("write:pets");
|
||||||
|
scope.append("read:pets");
|
||||||
|
auto token = _implicitFlow.getToken(scope.join(" "));
|
||||||
|
if(token.isValid())
|
||||||
|
input.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
|
||||||
|
_latestWorker = new PFXHttpRequestWorker(this, _manager);
|
||||||
|
_latestWorker->setTimeOut(_timeOut);
|
||||||
|
_latestWorker->setWorkingDirectory(_workingDirectory);
|
||||||
|
|
||||||
|
connect(_latestWorker, &PFXHttpRequestWorker::on_execution_finished, this, &PFXPetApi::addPetCallback);
|
||||||
|
connect(this, &PFXPetApi::abortRequestsSignal, _latestWorker, &QObject::deleteLater);
|
||||||
|
connect(_latestWorker, &QObject::destroyed, [this](){
|
||||||
|
if(findChildren<PFXHttpRequestWorker*>().count() == 0){
|
||||||
|
emit allPendingRequestsCompleted();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_latestInput = input;
|
||||||
|
_latestScope = scope;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
worker->execute(&input);
|
worker->execute(&input);
|
||||||
}
|
}
|
||||||
@ -272,6 +300,18 @@ void PFXPetApi::addPetCallback(PFXHttpRequestWorker *worker) {
|
|||||||
if (worker->error_type == QNetworkReply::NoError) {
|
if (worker->error_type == QNetworkReply::NoError) {
|
||||||
emit addPetSignal();
|
emit addPetSignal();
|
||||||
emit addPetSignalFull(worker);
|
emit addPetSignalFull(worker);
|
||||||
|
} else if(worker->error_type == QNetworkReply::AuthenticationRequiredError){
|
||||||
|
connect(&_implicitFlow, SIGNAL(tokenReceived()), this, SLOT(tokenAvailable()));
|
||||||
|
QStringList scope;
|
||||||
|
scope.append("write:pets");
|
||||||
|
scope.append("read:pets");
|
||||||
|
QString scopeStr = scope.join(" ");
|
||||||
|
QString authorizationUrl("http://petstore.swagger.io/api/oauth/dialog");
|
||||||
|
//TODO get clientID and Secret and state in the config? https://swagger.io/docs/specification/authentication/oauth2/ states that you should do as you like
|
||||||
|
_implicitFlow.setVariables(authorizationUrl, scopeStr, "state" , "http://127.0.0.1:9999", "clientId");
|
||||||
|
emit _implicitFlow.authenticationNeeded();
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
emit addPetSignalE(error_type, error_str);
|
emit addPetSignalE(error_type, error_str);
|
||||||
emit addPetSignalEFull(worker, error_type, error_str);
|
emit addPetSignalEFull(worker, error_type, error_str);
|
||||||
@ -324,6 +364,34 @@ void PFXPetApi::deletePet(const qint64 &pet_id, const ::test_namespace::Optional
|
|||||||
emit allPendingRequestsCompleted();
|
emit allPendingRequestsCompleted();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
_OauthMethod = 1;
|
||||||
|
_implicitFlow.link();
|
||||||
|
_passwordFlow.unlink();
|
||||||
|
_authFlow.unlink();
|
||||||
|
_credentialFlow.unlink();
|
||||||
|
QStringList scope;
|
||||||
|
scope.append("write:pets");
|
||||||
|
scope.append("read:pets");
|
||||||
|
auto token = _implicitFlow.getToken(scope.join(" "));
|
||||||
|
if(token.isValid())
|
||||||
|
input.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
|
||||||
|
_latestWorker = new PFXHttpRequestWorker(this, _manager);
|
||||||
|
_latestWorker->setTimeOut(_timeOut);
|
||||||
|
_latestWorker->setWorkingDirectory(_workingDirectory);
|
||||||
|
|
||||||
|
connect(_latestWorker, &PFXHttpRequestWorker::on_execution_finished, this, &PFXPetApi::deletePetCallback);
|
||||||
|
connect(this, &PFXPetApi::abortRequestsSignal, _latestWorker, &QObject::deleteLater);
|
||||||
|
connect(_latestWorker, &QObject::destroyed, [this](){
|
||||||
|
if(findChildren<PFXHttpRequestWorker*>().count() == 0){
|
||||||
|
emit allPendingRequestsCompleted();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_latestInput = input;
|
||||||
|
_latestScope = scope;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
worker->execute(&input);
|
worker->execute(&input);
|
||||||
}
|
}
|
||||||
@ -340,6 +408,18 @@ void PFXPetApi::deletePetCallback(PFXHttpRequestWorker *worker) {
|
|||||||
if (worker->error_type == QNetworkReply::NoError) {
|
if (worker->error_type == QNetworkReply::NoError) {
|
||||||
emit deletePetSignal();
|
emit deletePetSignal();
|
||||||
emit deletePetSignalFull(worker);
|
emit deletePetSignalFull(worker);
|
||||||
|
} else if(worker->error_type == QNetworkReply::AuthenticationRequiredError){
|
||||||
|
connect(&_implicitFlow, SIGNAL(tokenReceived()), this, SLOT(tokenAvailable()));
|
||||||
|
QStringList scope;
|
||||||
|
scope.append("write:pets");
|
||||||
|
scope.append("read:pets");
|
||||||
|
QString scopeStr = scope.join(" ");
|
||||||
|
QString authorizationUrl("http://petstore.swagger.io/api/oauth/dialog");
|
||||||
|
//TODO get clientID and Secret and state in the config? https://swagger.io/docs/specification/authentication/oauth2/ states that you should do as you like
|
||||||
|
_implicitFlow.setVariables(authorizationUrl, scopeStr, "state" , "http://127.0.0.1:9999", "clientId");
|
||||||
|
emit _implicitFlow.authenticationNeeded();
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
emit deletePetSignalE(error_type, error_str);
|
emit deletePetSignalE(error_type, error_str);
|
||||||
emit deletePetSignalEFull(worker, error_type, error_str);
|
emit deletePetSignalEFull(worker, error_type, error_str);
|
||||||
@ -458,6 +538,34 @@ void PFXPetApi::findPetsByStatus(const QList<QString> &status) {
|
|||||||
emit allPendingRequestsCompleted();
|
emit allPendingRequestsCompleted();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
_OauthMethod = 1;
|
||||||
|
_implicitFlow.link();
|
||||||
|
_passwordFlow.unlink();
|
||||||
|
_authFlow.unlink();
|
||||||
|
_credentialFlow.unlink();
|
||||||
|
QStringList scope;
|
||||||
|
scope.append("write:pets");
|
||||||
|
scope.append("read:pets");
|
||||||
|
auto token = _implicitFlow.getToken(scope.join(" "));
|
||||||
|
if(token.isValid())
|
||||||
|
input.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
|
||||||
|
_latestWorker = new PFXHttpRequestWorker(this, _manager);
|
||||||
|
_latestWorker->setTimeOut(_timeOut);
|
||||||
|
_latestWorker->setWorkingDirectory(_workingDirectory);
|
||||||
|
|
||||||
|
connect(_latestWorker, &PFXHttpRequestWorker::on_execution_finished, this, &PFXPetApi::findPetsByStatusCallback);
|
||||||
|
connect(this, &PFXPetApi::abortRequestsSignal, _latestWorker, &QObject::deleteLater);
|
||||||
|
connect(_latestWorker, &QObject::destroyed, [this](){
|
||||||
|
if(findChildren<PFXHttpRequestWorker*>().count() == 0){
|
||||||
|
emit allPendingRequestsCompleted();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_latestInput = input;
|
||||||
|
_latestScope = scope;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
worker->execute(&input);
|
worker->execute(&input);
|
||||||
}
|
}
|
||||||
@ -484,6 +592,18 @@ void PFXPetApi::findPetsByStatusCallback(PFXHttpRequestWorker *worker) {
|
|||||||
if (worker->error_type == QNetworkReply::NoError) {
|
if (worker->error_type == QNetworkReply::NoError) {
|
||||||
emit findPetsByStatusSignal(output);
|
emit findPetsByStatusSignal(output);
|
||||||
emit findPetsByStatusSignalFull(worker, output);
|
emit findPetsByStatusSignalFull(worker, output);
|
||||||
|
} else if(worker->error_type == QNetworkReply::AuthenticationRequiredError){
|
||||||
|
connect(&_implicitFlow, SIGNAL(tokenReceived()), this, SLOT(tokenAvailable()));
|
||||||
|
QStringList scope;
|
||||||
|
scope.append("write:pets");
|
||||||
|
scope.append("read:pets");
|
||||||
|
QString scopeStr = scope.join(" ");
|
||||||
|
QString authorizationUrl("http://petstore.swagger.io/api/oauth/dialog");
|
||||||
|
//TODO get clientID and Secret and state in the config? https://swagger.io/docs/specification/authentication/oauth2/ states that you should do as you like
|
||||||
|
_implicitFlow.setVariables(authorizationUrl, scopeStr, "state" , "http://127.0.0.1:9999", "clientId");
|
||||||
|
emit _implicitFlow.authenticationNeeded();
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
emit findPetsByStatusSignalE(output, error_type, error_str);
|
emit findPetsByStatusSignalE(output, error_type, error_str);
|
||||||
emit findPetsByStatusSignalEFull(worker, error_type, error_str);
|
emit findPetsByStatusSignalEFull(worker, error_type, error_str);
|
||||||
@ -602,6 +722,34 @@ void PFXPetApi::findPetsByTags(const QList<QString> &tags) {
|
|||||||
emit allPendingRequestsCompleted();
|
emit allPendingRequestsCompleted();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
_OauthMethod = 1;
|
||||||
|
_implicitFlow.link();
|
||||||
|
_passwordFlow.unlink();
|
||||||
|
_authFlow.unlink();
|
||||||
|
_credentialFlow.unlink();
|
||||||
|
QStringList scope;
|
||||||
|
scope.append("write:pets");
|
||||||
|
scope.append("read:pets");
|
||||||
|
auto token = _implicitFlow.getToken(scope.join(" "));
|
||||||
|
if(token.isValid())
|
||||||
|
input.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
|
||||||
|
_latestWorker = new PFXHttpRequestWorker(this, _manager);
|
||||||
|
_latestWorker->setTimeOut(_timeOut);
|
||||||
|
_latestWorker->setWorkingDirectory(_workingDirectory);
|
||||||
|
|
||||||
|
connect(_latestWorker, &PFXHttpRequestWorker::on_execution_finished, this, &PFXPetApi::findPetsByTagsCallback);
|
||||||
|
connect(this, &PFXPetApi::abortRequestsSignal, _latestWorker, &QObject::deleteLater);
|
||||||
|
connect(_latestWorker, &QObject::destroyed, [this](){
|
||||||
|
if(findChildren<PFXHttpRequestWorker*>().count() == 0){
|
||||||
|
emit allPendingRequestsCompleted();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_latestInput = input;
|
||||||
|
_latestScope = scope;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
worker->execute(&input);
|
worker->execute(&input);
|
||||||
}
|
}
|
||||||
@ -628,6 +776,18 @@ void PFXPetApi::findPetsByTagsCallback(PFXHttpRequestWorker *worker) {
|
|||||||
if (worker->error_type == QNetworkReply::NoError) {
|
if (worker->error_type == QNetworkReply::NoError) {
|
||||||
emit findPetsByTagsSignal(output);
|
emit findPetsByTagsSignal(output);
|
||||||
emit findPetsByTagsSignalFull(worker, output);
|
emit findPetsByTagsSignalFull(worker, output);
|
||||||
|
} else if(worker->error_type == QNetworkReply::AuthenticationRequiredError){
|
||||||
|
connect(&_implicitFlow, SIGNAL(tokenReceived()), this, SLOT(tokenAvailable()));
|
||||||
|
QStringList scope;
|
||||||
|
scope.append("write:pets");
|
||||||
|
scope.append("read:pets");
|
||||||
|
QString scopeStr = scope.join(" ");
|
||||||
|
QString authorizationUrl("http://petstore.swagger.io/api/oauth/dialog");
|
||||||
|
//TODO get clientID and Secret and state in the config? https://swagger.io/docs/specification/authentication/oauth2/ states that you should do as you like
|
||||||
|
_implicitFlow.setVariables(authorizationUrl, scopeStr, "state" , "http://127.0.0.1:9999", "clientId");
|
||||||
|
emit _implicitFlow.authenticationNeeded();
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
emit findPetsByTagsSignalE(output, error_type, error_str);
|
emit findPetsByTagsSignalE(output, error_type, error_str);
|
||||||
emit findPetsByTagsSignalEFull(worker, error_type, error_str);
|
emit findPetsByTagsSignalEFull(worker, error_type, error_str);
|
||||||
@ -731,6 +891,34 @@ void PFXPetApi::updatePet(const PFXPet &body) {
|
|||||||
emit allPendingRequestsCompleted();
|
emit allPendingRequestsCompleted();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
_OauthMethod = 1;
|
||||||
|
_implicitFlow.link();
|
||||||
|
_passwordFlow.unlink();
|
||||||
|
_authFlow.unlink();
|
||||||
|
_credentialFlow.unlink();
|
||||||
|
QStringList scope;
|
||||||
|
scope.append("write:pets");
|
||||||
|
scope.append("read:pets");
|
||||||
|
auto token = _implicitFlow.getToken(scope.join(" "));
|
||||||
|
if(token.isValid())
|
||||||
|
input.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
|
||||||
|
_latestWorker = new PFXHttpRequestWorker(this, _manager);
|
||||||
|
_latestWorker->setTimeOut(_timeOut);
|
||||||
|
_latestWorker->setWorkingDirectory(_workingDirectory);
|
||||||
|
|
||||||
|
connect(_latestWorker, &PFXHttpRequestWorker::on_execution_finished, this, &PFXPetApi::updatePetCallback);
|
||||||
|
connect(this, &PFXPetApi::abortRequestsSignal, _latestWorker, &QObject::deleteLater);
|
||||||
|
connect(_latestWorker, &QObject::destroyed, [this](){
|
||||||
|
if(findChildren<PFXHttpRequestWorker*>().count() == 0){
|
||||||
|
emit allPendingRequestsCompleted();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_latestInput = input;
|
||||||
|
_latestScope = scope;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
worker->execute(&input);
|
worker->execute(&input);
|
||||||
}
|
}
|
||||||
@ -747,6 +935,18 @@ void PFXPetApi::updatePetCallback(PFXHttpRequestWorker *worker) {
|
|||||||
if (worker->error_type == QNetworkReply::NoError) {
|
if (worker->error_type == QNetworkReply::NoError) {
|
||||||
emit updatePetSignal();
|
emit updatePetSignal();
|
||||||
emit updatePetSignalFull(worker);
|
emit updatePetSignalFull(worker);
|
||||||
|
} else if(worker->error_type == QNetworkReply::AuthenticationRequiredError){
|
||||||
|
connect(&_implicitFlow, SIGNAL(tokenReceived()), this, SLOT(tokenAvailable()));
|
||||||
|
QStringList scope;
|
||||||
|
scope.append("write:pets");
|
||||||
|
scope.append("read:pets");
|
||||||
|
QString scopeStr = scope.join(" ");
|
||||||
|
QString authorizationUrl("http://petstore.swagger.io/api/oauth/dialog");
|
||||||
|
//TODO get clientID and Secret and state in the config? https://swagger.io/docs/specification/authentication/oauth2/ states that you should do as you like
|
||||||
|
_implicitFlow.setVariables(authorizationUrl, scopeStr, "state" , "http://127.0.0.1:9999", "clientId");
|
||||||
|
emit _implicitFlow.authenticationNeeded();
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
emit updatePetSignalE(error_type, error_str);
|
emit updatePetSignalE(error_type, error_str);
|
||||||
emit updatePetSignalEFull(worker, error_type, error_str);
|
emit updatePetSignalEFull(worker, error_type, error_str);
|
||||||
@ -801,6 +1001,34 @@ void PFXPetApi::updatePetWithForm(const qint64 &pet_id, const ::test_namespace::
|
|||||||
emit allPendingRequestsCompleted();
|
emit allPendingRequestsCompleted();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
_OauthMethod = 1;
|
||||||
|
_implicitFlow.link();
|
||||||
|
_passwordFlow.unlink();
|
||||||
|
_authFlow.unlink();
|
||||||
|
_credentialFlow.unlink();
|
||||||
|
QStringList scope;
|
||||||
|
scope.append("write:pets");
|
||||||
|
scope.append("read:pets");
|
||||||
|
auto token = _implicitFlow.getToken(scope.join(" "));
|
||||||
|
if(token.isValid())
|
||||||
|
input.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
|
||||||
|
_latestWorker = new PFXHttpRequestWorker(this, _manager);
|
||||||
|
_latestWorker->setTimeOut(_timeOut);
|
||||||
|
_latestWorker->setWorkingDirectory(_workingDirectory);
|
||||||
|
|
||||||
|
connect(_latestWorker, &PFXHttpRequestWorker::on_execution_finished, this, &PFXPetApi::updatePetWithFormCallback);
|
||||||
|
connect(this, &PFXPetApi::abortRequestsSignal, _latestWorker, &QObject::deleteLater);
|
||||||
|
connect(_latestWorker, &QObject::destroyed, [this](){
|
||||||
|
if(findChildren<PFXHttpRequestWorker*>().count() == 0){
|
||||||
|
emit allPendingRequestsCompleted();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_latestInput = input;
|
||||||
|
_latestScope = scope;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
worker->execute(&input);
|
worker->execute(&input);
|
||||||
}
|
}
|
||||||
@ -817,6 +1045,18 @@ void PFXPetApi::updatePetWithFormCallback(PFXHttpRequestWorker *worker) {
|
|||||||
if (worker->error_type == QNetworkReply::NoError) {
|
if (worker->error_type == QNetworkReply::NoError) {
|
||||||
emit updatePetWithFormSignal();
|
emit updatePetWithFormSignal();
|
||||||
emit updatePetWithFormSignalFull(worker);
|
emit updatePetWithFormSignalFull(worker);
|
||||||
|
} else if(worker->error_type == QNetworkReply::AuthenticationRequiredError){
|
||||||
|
connect(&_implicitFlow, SIGNAL(tokenReceived()), this, SLOT(tokenAvailable()));
|
||||||
|
QStringList scope;
|
||||||
|
scope.append("write:pets");
|
||||||
|
scope.append("read:pets");
|
||||||
|
QString scopeStr = scope.join(" ");
|
||||||
|
QString authorizationUrl("http://petstore.swagger.io/api/oauth/dialog");
|
||||||
|
//TODO get clientID and Secret and state in the config? https://swagger.io/docs/specification/authentication/oauth2/ states that you should do as you like
|
||||||
|
_implicitFlow.setVariables(authorizationUrl, scopeStr, "state" , "http://127.0.0.1:9999", "clientId");
|
||||||
|
emit _implicitFlow.authenticationNeeded();
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
emit updatePetWithFormSignalE(error_type, error_str);
|
emit updatePetWithFormSignalE(error_type, error_str);
|
||||||
emit updatePetWithFormSignalEFull(worker, error_type, error_str);
|
emit updatePetWithFormSignalEFull(worker, error_type, error_str);
|
||||||
@ -871,6 +1111,34 @@ void PFXPetApi::uploadFile(const qint64 &pet_id, const ::test_namespace::Optiona
|
|||||||
emit allPendingRequestsCompleted();
|
emit allPendingRequestsCompleted();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
_OauthMethod = 1;
|
||||||
|
_implicitFlow.link();
|
||||||
|
_passwordFlow.unlink();
|
||||||
|
_authFlow.unlink();
|
||||||
|
_credentialFlow.unlink();
|
||||||
|
QStringList scope;
|
||||||
|
scope.append("write:pets");
|
||||||
|
scope.append("read:pets");
|
||||||
|
auto token = _implicitFlow.getToken(scope.join(" "));
|
||||||
|
if(token.isValid())
|
||||||
|
input.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
|
||||||
|
_latestWorker = new PFXHttpRequestWorker(this, _manager);
|
||||||
|
_latestWorker->setTimeOut(_timeOut);
|
||||||
|
_latestWorker->setWorkingDirectory(_workingDirectory);
|
||||||
|
|
||||||
|
connect(_latestWorker, &PFXHttpRequestWorker::on_execution_finished, this, &PFXPetApi::uploadFileCallback);
|
||||||
|
connect(this, &PFXPetApi::abortRequestsSignal, _latestWorker, &QObject::deleteLater);
|
||||||
|
connect(_latestWorker, &QObject::destroyed, [this](){
|
||||||
|
if(findChildren<PFXHttpRequestWorker*>().count() == 0){
|
||||||
|
emit allPendingRequestsCompleted();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_latestInput = input;
|
||||||
|
_latestScope = scope;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
worker->execute(&input);
|
worker->execute(&input);
|
||||||
}
|
}
|
||||||
@ -888,10 +1156,71 @@ void PFXPetApi::uploadFileCallback(PFXHttpRequestWorker *worker) {
|
|||||||
if (worker->error_type == QNetworkReply::NoError) {
|
if (worker->error_type == QNetworkReply::NoError) {
|
||||||
emit uploadFileSignal(output);
|
emit uploadFileSignal(output);
|
||||||
emit uploadFileSignalFull(worker, output);
|
emit uploadFileSignalFull(worker, output);
|
||||||
|
} else if(worker->error_type == QNetworkReply::AuthenticationRequiredError){
|
||||||
|
connect(&_implicitFlow, SIGNAL(tokenReceived()), this, SLOT(tokenAvailable()));
|
||||||
|
QStringList scope;
|
||||||
|
scope.append("write:pets");
|
||||||
|
scope.append("read:pets");
|
||||||
|
QString scopeStr = scope.join(" ");
|
||||||
|
QString authorizationUrl("http://petstore.swagger.io/api/oauth/dialog");
|
||||||
|
//TODO get clientID and Secret and state in the config? https://swagger.io/docs/specification/authentication/oauth2/ states that you should do as you like
|
||||||
|
_implicitFlow.setVariables(authorizationUrl, scopeStr, "state" , "http://127.0.0.1:9999", "clientId");
|
||||||
|
emit _implicitFlow.authenticationNeeded();
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
emit uploadFileSignalE(output, error_type, error_str);
|
emit uploadFileSignalE(output, error_type, error_str);
|
||||||
emit uploadFileSignalEFull(worker, error_type, error_str);
|
emit uploadFileSignalEFull(worker, error_type, error_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PFXPetApi::tokenAvailable(){
|
||||||
|
|
||||||
|
oauthToken token;
|
||||||
|
switch (_OauthMethod) {
|
||||||
|
case 1: //implicit flow
|
||||||
|
token = _implicitFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_implicitFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: //authorization flow
|
||||||
|
token = _authFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_authFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: //client credentials flow
|
||||||
|
token = _credentialFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_credentialFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4: //resource owner password flow
|
||||||
|
token = _passwordFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_credentialFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qDebug() << "No Oauth method set!";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace test_namespace
|
} // namespace test_namespace
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "PFXHelpers.h"
|
#include "PFXHelpers.h"
|
||||||
#include "PFXHttpRequest.h"
|
#include "PFXHttpRequest.h"
|
||||||
#include "PFXServerConfiguration.h"
|
#include "PFXServerConfiguration.h"
|
||||||
|
#include "PFXOauth.h"
|
||||||
|
|
||||||
#include "PFXApiResponse.h"
|
#include "PFXApiResponse.h"
|
||||||
#include "PFXHttpFileElement.h"
|
#include "PFXHttpFileElement.h"
|
||||||
@ -116,6 +117,14 @@ private:
|
|||||||
QMap<QString, QString> _defaultHeaders;
|
QMap<QString, QString> _defaultHeaders;
|
||||||
bool _isResponseCompressionEnabled;
|
bool _isResponseCompressionEnabled;
|
||||||
bool _isRequestCompressionEnabled;
|
bool _isRequestCompressionEnabled;
|
||||||
|
PFXHttpRequestInput _latestInput;
|
||||||
|
PFXHttpRequestWorker *_latestWorker;
|
||||||
|
QStringList _latestScope;
|
||||||
|
OauthCode _authFlow;
|
||||||
|
OauthImplicit _implicitFlow;
|
||||||
|
OauthCredentials _credentialFlow;
|
||||||
|
OauthPassword _passwordFlow;
|
||||||
|
int _OauthMethod = 0;
|
||||||
|
|
||||||
void addPetCallback(PFXHttpRequestWorker *worker);
|
void addPetCallback(PFXHttpRequestWorker *worker);
|
||||||
void deletePetCallback(PFXHttpRequestWorker *worker);
|
void deletePetCallback(PFXHttpRequestWorker *worker);
|
||||||
@ -166,6 +175,10 @@ signals:
|
|||||||
|
|
||||||
void abortRequestsSignal();
|
void abortRequestsSignal();
|
||||||
void allPendingRequestsCompleted();
|
void allPendingRequestsCompleted();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void tokenAvailable();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace test_namespace
|
} // namespace test_namespace
|
||||||
|
@ -458,4 +458,53 @@ void PFXStoreApi::placeOrderCallback(PFXHttpRequestWorker *worker) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PFXStoreApi::tokenAvailable(){
|
||||||
|
|
||||||
|
oauthToken token;
|
||||||
|
switch (_OauthMethod) {
|
||||||
|
case 1: //implicit flow
|
||||||
|
token = _implicitFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_implicitFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: //authorization flow
|
||||||
|
token = _authFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_authFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: //client credentials flow
|
||||||
|
token = _credentialFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_credentialFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4: //resource owner password flow
|
||||||
|
token = _passwordFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_credentialFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qDebug() << "No Oauth method set!";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace test_namespace
|
} // namespace test_namespace
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "PFXHelpers.h"
|
#include "PFXHelpers.h"
|
||||||
#include "PFXHttpRequest.h"
|
#include "PFXHttpRequest.h"
|
||||||
#include "PFXServerConfiguration.h"
|
#include "PFXServerConfiguration.h"
|
||||||
|
#include "PFXOauth.h"
|
||||||
|
|
||||||
#include "PFXOrder.h"
|
#include "PFXOrder.h"
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
@ -88,6 +89,14 @@ private:
|
|||||||
QMap<QString, QString> _defaultHeaders;
|
QMap<QString, QString> _defaultHeaders;
|
||||||
bool _isResponseCompressionEnabled;
|
bool _isResponseCompressionEnabled;
|
||||||
bool _isRequestCompressionEnabled;
|
bool _isRequestCompressionEnabled;
|
||||||
|
PFXHttpRequestInput _latestInput;
|
||||||
|
PFXHttpRequestWorker *_latestWorker;
|
||||||
|
QStringList _latestScope;
|
||||||
|
OauthCode _authFlow;
|
||||||
|
OauthImplicit _implicitFlow;
|
||||||
|
OauthCredentials _credentialFlow;
|
||||||
|
OauthPassword _passwordFlow;
|
||||||
|
int _OauthMethod = 0;
|
||||||
|
|
||||||
void deleteOrderCallback(PFXHttpRequestWorker *worker);
|
void deleteOrderCallback(PFXHttpRequestWorker *worker);
|
||||||
void getInventoryCallback(PFXHttpRequestWorker *worker);
|
void getInventoryCallback(PFXHttpRequestWorker *worker);
|
||||||
@ -118,6 +127,10 @@ signals:
|
|||||||
|
|
||||||
void abortRequestsSignal();
|
void abortRequestsSignal();
|
||||||
void allPendingRequestsCompleted();
|
void allPendingRequestsCompleted();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void tokenAvailable();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace test_namespace
|
} // namespace test_namespace
|
||||||
|
@ -702,4 +702,53 @@ void PFXUserApi::updateUserCallback(PFXHttpRequestWorker *worker) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PFXUserApi::tokenAvailable(){
|
||||||
|
|
||||||
|
oauthToken token;
|
||||||
|
switch (_OauthMethod) {
|
||||||
|
case 1: //implicit flow
|
||||||
|
token = _implicitFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_implicitFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: //authorization flow
|
||||||
|
token = _authFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_authFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: //client credentials flow
|
||||||
|
token = _credentialFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_credentialFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4: //resource owner password flow
|
||||||
|
token = _passwordFlow.getToken(_latestScope.join(" "));
|
||||||
|
if(token.isValid()){
|
||||||
|
_latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
|
||||||
|
_latestWorker->execute(&_latestInput);
|
||||||
|
}else{
|
||||||
|
_credentialFlow.removeToken(_latestScope.join(" "));
|
||||||
|
qDebug() << "Could not retreive a valid token";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qDebug() << "No Oauth method set!";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace test_namespace
|
} // namespace test_namespace
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "PFXHelpers.h"
|
#include "PFXHelpers.h"
|
||||||
#include "PFXHttpRequest.h"
|
#include "PFXHttpRequest.h"
|
||||||
#include "PFXServerConfiguration.h"
|
#include "PFXServerConfiguration.h"
|
||||||
|
#include "PFXOauth.h"
|
||||||
|
|
||||||
#include "PFXUser.h"
|
#include "PFXUser.h"
|
||||||
#include <QList>
|
#include <QList>
|
||||||
@ -110,6 +111,14 @@ private:
|
|||||||
QMap<QString, QString> _defaultHeaders;
|
QMap<QString, QString> _defaultHeaders;
|
||||||
bool _isResponseCompressionEnabled;
|
bool _isResponseCompressionEnabled;
|
||||||
bool _isRequestCompressionEnabled;
|
bool _isRequestCompressionEnabled;
|
||||||
|
PFXHttpRequestInput _latestInput;
|
||||||
|
PFXHttpRequestWorker *_latestWorker;
|
||||||
|
QStringList _latestScope;
|
||||||
|
OauthCode _authFlow;
|
||||||
|
OauthImplicit _implicitFlow;
|
||||||
|
OauthCredentials _credentialFlow;
|
||||||
|
OauthPassword _passwordFlow;
|
||||||
|
int _OauthMethod = 0;
|
||||||
|
|
||||||
void createUserCallback(PFXHttpRequestWorker *worker);
|
void createUserCallback(PFXHttpRequestWorker *worker);
|
||||||
void createUsersWithArrayInputCallback(PFXHttpRequestWorker *worker);
|
void createUsersWithArrayInputCallback(PFXHttpRequestWorker *worker);
|
||||||
@ -160,6 +169,10 @@ signals:
|
|||||||
|
|
||||||
void abortRequestsSignal();
|
void abortRequestsSignal();
|
||||||
void allPendingRequestsCompleted();
|
void allPendingRequestsCompleted();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void tokenAvailable();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace test_namespace
|
} // namespace test_namespace
|
||||||
|
@ -19,7 +19,8 @@ HEADERS += \
|
|||||||
$${PWD}/PFXEnum.h \
|
$${PWD}/PFXEnum.h \
|
||||||
$${PWD}/PFXHttpFileElement.h \
|
$${PWD}/PFXHttpFileElement.h \
|
||||||
$${PWD}/PFXServerConfiguration.h \
|
$${PWD}/PFXServerConfiguration.h \
|
||||||
$${PWD}/PFXServerVariable.h
|
$${PWD}/PFXServerVariable.h \
|
||||||
|
$${PWD}/PFXOauth.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
# Models
|
# Models
|
||||||
@ -36,4 +37,5 @@ SOURCES += \
|
|||||||
# Others
|
# Others
|
||||||
$${PWD}/PFXHelpers.cpp \
|
$${PWD}/PFXHelpers.cpp \
|
||||||
$${PWD}/PFXHttpRequest.cpp \
|
$${PWD}/PFXHttpRequest.cpp \
|
||||||
$${PWD}/PFXHttpFileElement.cpp
|
$${PWD}/PFXHttpFileElement.cpp \
|
||||||
|
$${PWD}/PFXOauth.cpp
|
||||||
|
Loading…
x
Reference in New Issue
Block a user