1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef QT_NO_HTTP
5
6#include "qoauthoobreplyhandler.h"
7#include "qabstractoauthreplyhandler_p.h"
8
9#include <QtCore/qurlquery.h>
10#include <QtCore/qjsonobject.h>
11#include <QtCore/qjsondocument.h>
12#include <QtCore/qloggingcategory.h>
13
14#include <QtNetwork/qnetworkreply.h>
15
16QT_BEGIN_NAMESPACE
17
18using namespace Qt::StringLiterals;
19
20QOAuthOobReplyHandler::QOAuthOobReplyHandler(QObject *parent)
21 : QAbstractOAuthReplyHandler(parent)
22{}
23
24QString QOAuthOobReplyHandler::callback() const
25{
26 return QStringLiteral("oob");
27}
28
29void QOAuthOobReplyHandler::networkReplyFinished(QNetworkReply *reply)
30{
31 if (reply->error() != QNetworkReply::NoError) {
32 emit tokenRequestErrorOccurred(error: QAbstractOAuth::Error::NetworkError, errorString: reply->errorString());
33 return;
34 }
35 if (reply->header(header: QNetworkRequest::ContentTypeHeader).isNull()) {
36 emit tokenRequestErrorOccurred(error: QAbstractOAuth::Error::NetworkError,
37 errorString: u"Empty Content-type header"_s);
38 return;
39 }
40 const QString contentType = reply->header(header: QNetworkRequest::ContentTypeHeader).isNull() ?
41 QStringLiteral("text/html") :
42 reply->header(header: QNetworkRequest::ContentTypeHeader).toString();
43 const QByteArray data = reply->readAll();
44 if (data.isEmpty()) {
45 emit tokenRequestErrorOccurred(error: QAbstractOAuth::Error::NetworkError, errorString: u"No received data"_s);
46 return;
47 }
48
49 Q_EMIT replyDataReceived(data);
50
51 QVariantMap ret;
52
53 if (contentType.startsWith(QStringLiteral("text/html")) ||
54 contentType.startsWith(QStringLiteral("application/x-www-form-urlencoded"))) {
55 ret = parseResponse(response: data);
56 } else if (contentType.startsWith(QStringLiteral("application/json"))
57 || contentType.startsWith(QStringLiteral("text/javascript"))) {
58 const QJsonDocument document = QJsonDocument::fromJson(json: data);
59 if (!document.isObject()) {
60 emit tokenRequestErrorOccurred(error: QAbstractOAuth::Error::ServerError,
61 errorString: u"Received data is not a JSON object: %1"_s.arg(a: QString::fromUtf8(ba: data)));
62 return;
63 }
64 const QJsonObject object = document.object();
65 if (object.isEmpty()) {
66 qCWarning(lcReplyHandler, "Received empty JSON object: %s",
67 qPrintable(QString::fromUtf8(data)));
68 }
69 ret = object.toVariantMap();
70 } else {
71 emit tokenRequestErrorOccurred(error: QAbstractOAuth::Error::ServerError,
72 errorString: u"Unknown Content-type %1"_s.arg(a: contentType));
73 return;
74 }
75
76 Q_EMIT tokensReceived(tokens: ret);
77}
78
79QVariantMap QOAuthOobReplyHandler::parseResponse(const QByteArray &response)
80{
81 QVariantMap ret;
82 QUrlQuery query(QString::fromUtf8(ba: response));
83 auto queryItems = query.queryItems(encoding: QUrl::FullyDecoded);
84 for (auto it = queryItems.begin(), end = queryItems.end(); it != end; ++it)
85 ret.insert(key: it->first, value: it->second);
86 return ret;
87}
88
89QT_END_NAMESPACE
90
91#include "moc_qoauthoobreplyhandler.cpp"
92
93#endif // QT_NO_HTTP
94

source code of qtnetworkauth/src/oauth/qoauthoobreplyhandler.cpp