mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-05-12 20:50:55 +00:00
346 lines
10 KiB
C++
346 lines
10 KiB
C++
#include "PFXOauth.h"
|
|
|
|
namespace test_namespace {
|
|
|
|
/*
|
|
* 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);
|
|
Q_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, nullptr, nullptr, nullptr);
|
|
disconnect(&m_server, nullptr, nullptr, nullptr);
|
|
}
|
|
|
|
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, nullptr, nullptr, nullptr);
|
|
disconnect(&m_server, nullptr, nullptr, nullptr);
|
|
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, nullptr, nullptr, nullptr);
|
|
}
|
|
|
|
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, nullptr, nullptr, nullptr);
|
|
}
|
|
|
|
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;
|
|
for (auto 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();
|
|
|
|
Q_EMIT dataReceived(queryParams);
|
|
}
|
|
|
|
} // namespace test_namespace
|