Changeset View
Standalone View
providers/ghprovider/ghresource.cpp
Show All 30 Lines | |||||
31 | #include <ghprovidermodel.h> | 31 | #include <ghprovidermodel.h> | ||
32 | 32 | | |||
33 | 33 | | |||
34 | namespace gh | 34 | namespace gh | ||
35 | { | 35 | { | ||
36 | /// Base url for the Github API v3. | 36 | /// Base url for the Github API v3. | ||
37 | const static QUrl baseUrl(QStringLiteral("https://api.github.com")); | 37 | const static QUrl baseUrl(QStringLiteral("https://api.github.com")); | ||
38 | 38 | | |||
39 | KIO::StoredTransferJob* createHttpAuthJob(const QString &httpHeader) | ||||
mwolff: get -> create | |||||
40 | { | ||||
41 | QUrl url = baseUrl; | ||||
42 | url = url.adjusted(QUrl::StripTrailingSlash); | ||||
43 | url.setPath(url.path() + QLatin1String("/authorizations")); | ||||
mwolff: + QLatin1String("//authorizations")
is the double-slash really needed? | |||||
44 | | ||||
mwolff: QByteArrayLiteral | |||||
45 | // generate a unique token, see bug 372144 | ||||
46 | const QString tokenName = "KDevelop Github Provider : " | ||||
mwolff: QStringLiteral | |||||
47 | + QHostInfo::localHostName() + " - " | ||||
48 | + QDateTime::currentDateTimeUtc().toString(); | ||||
49 | const QByteArray data = QByteArrayLiteral("{ \"scopes\": [\"repo\"], \"note\": \"") + tokenName.toUtf8() + QByteArrayLiteral("\" }"); | ||||
50 | | ||||
51 | KIO::StoredTransferJob *job = KIO::storedHttpPost(data, url, KIO::HideProgressInfo); | ||||
52 | job->setProperty("requestedTokenName", tokenName); | ||||
53 | job->addMetaData(QStringLiteral("customHTTPHeader"), httpHeader); | ||||
54 | | ||||
55 | return job; | ||||
56 | } | ||||
57 | | ||||
39 | Resource::Resource(QObject *parent, ProviderModel *model) | 58 | Resource::Resource(QObject *parent, ProviderModel *model) | ||
40 | : QObject(parent), m_model(model) | 59 | : QObject(parent), m_model(model) | ||
41 | { | 60 | { | ||
42 | /* There's nothing to do here */ | 61 | /* There's nothing to do here */ | ||
43 | } | 62 | } | ||
44 | 63 | | |||
45 | void Resource::searchRepos(const QString &uri, const QString &token) | 64 | void Resource::searchRepos(const QString &uri, const QString &token) | ||
46 | { | 65 | { | ||
47 | KIO::TransferJob *job = getTransferJob(uri, token); | 66 | KIO::TransferJob *job = getTransferJob(uri, token); | ||
48 | connect(job, &KIO::TransferJob::data, | 67 | connect(job, &KIO::TransferJob::data, | ||
49 | this, &Resource::slotRepos); | 68 | this, &Resource::slotRepos); | ||
50 | } | 69 | } | ||
51 | 70 | | |||
52 | void Resource::getOrgs(const QString &token) | 71 | void Resource::getOrgs(const QString &token) | ||
53 | { | 72 | { | ||
54 | KIO::TransferJob *job = getTransferJob(QStringLiteral("/user/orgs"), token); | 73 | KIO::TransferJob *job = getTransferJob(QStringLiteral("/user/orgs"), token); | ||
55 | connect(job, &KIO::TransferJob::data, | 74 | connect(job, &KIO::TransferJob::data, | ||
56 | this, &Resource::slotOrgs); | 75 | this, &Resource::slotOrgs); | ||
57 | } | 76 | } | ||
58 | 77 | | |||
59 | void Resource::authenticate(const QString &name, const QString &password) | 78 | void Resource::authenticate(const QString &name, const QString &password) | ||
60 | { | 79 | { | ||
61 | QUrl url = baseUrl; | 80 | auto job = createHttpAuthJob(QLatin1String("Authorization: Basic ") + QString::fromUtf8((name.toUtf8() + ':' + password.toUtf8()).toBase64())); | ||
62 | url = url.adjusted(QUrl::StripTrailingSlash); | 81 | job->addMetaData("PropagateHttpHeader","true"); | ||
63 | url.setPath(url.path() + '/' + "/authorizations"); | 82 | connect(job, &KIO::StoredTransferJob::result, | ||
64 | 83 | this, &Resource::slotAuthenticate); | |||
65 | // generate a unique token, see bug 372144 | 84 | job->start(); | ||
66 | const QString tokenName = "KDevelop Github Provider : " | 85 | } | ||
67 | + QHostInfo::localHostName() + " - " | | |||
68 | + QDateTime::currentDateTimeUtc().toString(); | | |||
69 | const QByteArray data = "{ \"scopes\": [\"repo\"], \"note\": \"" + tokenName.toUtf8() + "\" }"; | | |||
70 | 86 | | |||
71 | KIO::StoredTransferJob *job = KIO::storedHttpPost(data, url, KIO::HideProgressInfo); | 87 | void Resource::twoFactorAuthenticate(const QString &transferHeader, const QString &code) | ||
QLatin1String("Authorization: Basic ") + QString::fromUtf8((name.toUtf8() + ':' + password.toUtf8()).toBase64()) mwolff: QLatin1String("Authorization: Basic ") + QString::fromUtf8((name.toUtf8() + ':' + password. | |||||
72 | job->setProperty("requestedTokenName", tokenName); | 88 | { | ||
73 | job->addMetaData(QStringLiteral("customHTTPHeader"), "Authorization: Basic " + QString (name + ':' + password).toUtf8().toBase64()); | 89 | auto job = createHttpAuthJob(transferHeader + QLatin1String("\nX-GitHub-OTP: ") + code); | ||
74 | connect(job, &KIO::StoredTransferJob::result, this, &Resource::slotAuthenticate); | 90 | connect(job, &KIO::StoredTransferJob::result, | ||
91 | this, &Resource::slotAuthenticate); | ||||
75 | job->start(); | 92 | job->start(); | ||
76 | } | 93 | } | ||
kfunk: Newline before `{` | |||||
77 | 94 | | |||
mwolff: QLatin1String for the string literal in the middle | |||||
78 | void Resource::revokeAccess(const QString &id, const QString &name, const QString &password) | 95 | void Resource::revokeAccess(const QString &id, const QString &name, const QString &password) | ||
79 | { | 96 | { | ||
80 | QUrl url = baseUrl; | 97 | QUrl url = baseUrl; | ||
81 | url.setPath(url.path() + "/authorizations/" + id); | 98 | url.setPath(url.path() + "/authorizations/" + id); | ||
82 | KIO::TransferJob *job = KIO::http_delete(url, KIO::HideProgressInfo); | 99 | KIO::TransferJob *job = KIO::http_delete(url, KIO::HideProgressInfo); | ||
83 | job->addMetaData(QStringLiteral("customHTTPHeader"), "Authorization: Basic " + QString (name + ':' + password).toUtf8().toBase64()); | 100 | job->addMetaData(QStringLiteral("customHTTPHeader"), "Authorization: Basic " + QString (name + ':' + password).toUtf8().toBase64()); | ||
84 | /* And we don't care if it's successful ;) */ | 101 | /* And we don't care if it's successful ;) */ | ||
85 | job->start(); | 102 | job->start(); | ||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Line(s) | 159 | { | |||
143 | const QString tokenName = job->property("requestedTokenName").toString(); | 160 | const QString tokenName = job->property("requestedTokenName").toString(); | ||
144 | Q_ASSERT(!tokenName.isEmpty()); | 161 | Q_ASSERT(!tokenName.isEmpty()); | ||
145 | 162 | | |||
146 | if (job->error()) { | 163 | if (job->error()) { | ||
147 | emit authenticated("", "", tokenName); | 164 | emit authenticated("", "", tokenName); | ||
148 | return; | 165 | return; | ||
149 | } | 166 | } | ||
150 | 167 | | |||
168 | const auto metaData = qobject_cast<KIO::StoredTransferJob*>(job)->metaData(); | ||||
kfunk: `const ...` | |||||
169 | if (metaData[QStringLiteral("responsecode")] == QStringLiteral("401")) { | ||||
mwolff: QStringLiteral for the responsecode | |||||
170 | const auto& header = metaData[QStringLiteral("HTTP-Headers")]; | ||||
kfunk: `const auto&` | |||||
mwolff: QSL | |||||
171 | if (header.contains(QStringLiteral("X-GitHub-OTP: required;"), Qt::CaseInsensitive)) { | ||||
kfunk: Isn't the casing fixed? Can it really vary? | |||||
mwolff: QSL | |||||
"x-github-otp: required: Still incorrect casing. Does this work? https://developer.github.com/v3/auth/ says it's X-GitHub-OTP: required; kfunk: `"x-github-otp: required`: Still incorrect casing. Does this work?
https://developer.github. | |||||
Than it lies :) zhigalin: > https://developer.github.com/v3/auth/ says it's X-GitHub-OTP: required;
Than it lies :)
It's… | |||||
kfunk: Ugh.
Please add a note then :) | |||||
172 | emit twoFactorAuthRequested(qobject_cast<KIO::StoredTransferJob*>(job)->outgoingMetaData()[QStringLiteral("customHTTPHeader")]); | ||||
mwolff: QSL | |||||
Please pass m_tfHttpHeader via twoFactorRequested() instead I.e. add a parameter to that function. That way you can save the extra member in this class for m_tfHttpHeader. And in general: Please refrain from adding less known abbreviations to symbol names; it makes reading code harder. kfunk: Please pass `m_tfHttpHeader` via `twoFactorRequested()` instead I.e. add a parameter to that… | |||||
m_tfHttpHeader was created by the previous author, not me zhigalin: > And in general: Please refrain from adding less known abbreviations to symbol names; it makes… | |||||
173 | return; | ||||
174 | } | ||||
175 | } | ||||
176 | | ||||
151 | QJsonParseError error; | 177 | QJsonParseError error; | ||
152 | QJsonDocument doc = QJsonDocument::fromJson(qobject_cast<KIO::StoredTransferJob *>(job)->data(), &error); | 178 | QJsonDocument doc = QJsonDocument::fromJson(qobject_cast<KIO::StoredTransferJob *>(job)->data(), &error); | ||
153 | 179 | | |||
154 | qCDebug(GHPROVIDER) << "Response:" << doc; | 180 | qCDebug(GHPROVIDER) << "Response:" << doc; | ||
155 | 181 | | |||
156 | if (error.error == 0) { | 182 | if (error.error == 0) { | ||
157 | QVariantMap map = doc.toVariant().toMap(); | 183 | QVariantMap map = doc.toVariant().toMap(); | ||
158 | emit authenticated(map.value(QStringLiteral("id")).toByteArray(), | 184 | emit authenticated(map.value(QStringLiteral("id")).toByteArray(), | ||
▲ Show 20 Lines • Show All 46 Lines • Show Last 20 Lines |
get -> create