cpp-qt-client.oauth.cpp.mustache Maven / Gradle / Ivy
#include "{{prefix}}Oauth.h"
{{#cppNamespaceDeclarations}}
namespace {{this}} {
{{/cppNamespaceDeclarations}}
/*
* 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)), this, SLOT(onVerificationReceived(QMap)));
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 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)), this, SLOT(ImplicitTokenReceived(QMap)));
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 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(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"
<<"\
\
\
\
\
\
You can close this window now!
\
\
";
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 > tokens;
QUrlQuery query(getTokenUrl);
tokens = query.queryItems();
QMap 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);
}
{{#cppNamespaceDeclarations}}
} // namespace {{this}}
{{/cppNamespaceDeclarations}}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy