forked from qt-creator/qt-creator
Axivion: Make initial dashboard fetch a part of authorization
Ensure that after authorization we have fetched the initial dashboard info. If the fetch fails, we remove the stored ApiToken from the key chain. Change-Id: I894b9d8bc8ade8ec6fa29391fafa67ad5b4fabba Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -128,8 +128,27 @@ static QString credentialKey()
|
||||
return escape(settings().server.username) + '@' + escape(settings().server.dashboard);
|
||||
}
|
||||
|
||||
static DashboardInfo toDashboardInfo(const QUrl &source, const Dto::DashboardInfoDto &infoDto)
|
||||
template <typename DtoType>
|
||||
struct GetDtoStorage
|
||||
{
|
||||
QUrl url;
|
||||
std::optional<QByteArray> credential;
|
||||
std::optional<DtoType> dtoData;
|
||||
};
|
||||
|
||||
template <typename DtoType>
|
||||
struct PostDtoStorage
|
||||
{
|
||||
QUrl url;
|
||||
std::optional<QByteArray> credential;
|
||||
QByteArray csrfToken;
|
||||
QByteArray writeData;
|
||||
std::optional<DtoType> dtoData;
|
||||
};
|
||||
|
||||
static DashboardInfo toDashboardInfo(const GetDtoStorage<Dto::DashboardInfoDto> &dashboardStorage)
|
||||
{
|
||||
const Dto::DashboardInfoDto &infoDto = *dashboardStorage.dtoData;
|
||||
const QVersionNumber versionNumber = infoDto.dashboardVersionNumber
|
||||
? QVersionNumber::fromString(*infoDto.dashboardVersionNumber) : QVersionNumber();
|
||||
|
||||
@@ -142,7 +161,7 @@ static DashboardInfo toDashboardInfo(const QUrl &source, const Dto::DashboardInf
|
||||
projectUrls.insert(project.name, project.url);
|
||||
}
|
||||
}
|
||||
return {source, versionNumber, projects, projectUrls, infoDto.checkCredentialsUrl};
|
||||
return {dashboardStorage.url, versionNumber, projects, projectUrls, infoDto.checkCredentialsUrl};
|
||||
}
|
||||
|
||||
QString IssueListSearch::toQuery() const
|
||||
@@ -376,24 +395,6 @@ static Group fetchHtmlRecipe(const QUrl &url, const std::function<void(const QBy
|
||||
return {NetworkQueryTask(onQuerySetup, onQueryDone)};
|
||||
}
|
||||
|
||||
template <typename DtoType>
|
||||
struct GetDtoStorage
|
||||
{
|
||||
QUrl url;
|
||||
std::optional<QByteArray> credential;
|
||||
std::optional<DtoType> dtoData;
|
||||
};
|
||||
|
||||
template <typename DtoType>
|
||||
struct PostDtoStorage
|
||||
{
|
||||
QUrl url;
|
||||
std::optional<QByteArray> credential;
|
||||
QByteArray csrfToken;
|
||||
QByteArray writeData;
|
||||
std::optional<DtoType> dtoData;
|
||||
};
|
||||
|
||||
template <typename DtoType, template <typename> typename DtoStorageType>
|
||||
static Group dtoRecipe(const Storage<DtoStorageType<DtoType>> &dtoStorage)
|
||||
{
|
||||
@@ -419,7 +420,8 @@ static Group dtoRecipe(const Storage<DtoStorageType<DtoType>> &dtoStorage)
|
||||
query.setNetworkAccessManager(&dd->m_networkAccessManager);
|
||||
};
|
||||
|
||||
const auto onNetworkQueryDone = [storage](const NetworkQuery &query, DoneWith doneWith) {
|
||||
const auto onNetworkQueryDone = [storage, dtoStorage](const NetworkQuery &query,
|
||||
DoneWith doneWith) {
|
||||
QNetworkReply *reply = query.reply();
|
||||
const QNetworkReply::NetworkError error = reply->error();
|
||||
const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
@@ -432,6 +434,7 @@ static Group dtoRecipe(const Storage<DtoStorageType<DtoType>> &dtoStorage)
|
||||
if (doneWith == DoneWith::Success && statusCode == httpStatusCodeOk
|
||||
&& contentType == s_jsonContentType) {
|
||||
*storage = reply->readAll();
|
||||
dtoStorage->url = reply->url();
|
||||
return DoneResult::Success;
|
||||
}
|
||||
|
||||
@@ -521,8 +524,7 @@ static Group authorizationRecipe()
|
||||
const auto onUnauthorizedGroupDone = [unauthorizedDashboardStorage] {
|
||||
if (unauthorizedDashboardStorage->dtoData) {
|
||||
dd->m_serverAccess = ServerAccess::NoAuthorization;
|
||||
dd->m_dashboardInfo = toDashboardInfo(settings().server.dashboard,
|
||||
*unauthorizedDashboardStorage->dtoData);
|
||||
dd->m_dashboardInfo = toDashboardInfo(*unauthorizedDashboardStorage);
|
||||
} else {
|
||||
dd->m_serverAccess = ServerAccess::WithAuthorization;
|
||||
}
|
||||
@@ -549,7 +551,7 @@ static Group authorizationRecipe()
|
||||
|
||||
const Storage<QString> passwordStorage;
|
||||
const Storage<GetDtoStorage<Dto::DashboardInfoDto>> dashboardStorage;
|
||||
const auto onDashboardGroupSetup = [passwordStorage, dashboardStorage] {
|
||||
const auto onPasswordGroupSetup = [passwordStorage, dashboardStorage] {
|
||||
if (dd->m_apiToken)
|
||||
return SetupResult::StopWithSuccess;
|
||||
|
||||
@@ -572,8 +574,7 @@ static Group authorizationRecipe()
|
||||
if (!dashboardStorage->dtoData)
|
||||
return SetupResult::StopWithSuccess;
|
||||
|
||||
dd->m_dashboardInfo = toDashboardInfo(settings().server.dashboard,
|
||||
*dashboardStorage->dtoData);
|
||||
dd->m_dashboardInfo = toDashboardInfo(*dashboardStorage);
|
||||
|
||||
const Dto::DashboardInfoDto &dashboardDto = *dashboardStorage->dtoData;
|
||||
if (!dashboardDto.userApiTokenUrl)
|
||||
@@ -607,6 +608,29 @@ static Group authorizationRecipe()
|
||||
return DoneResult::Success;
|
||||
};
|
||||
|
||||
const auto onDashboardGroupSetup = [dashboardStorage] {
|
||||
if (dd->m_dashboardInfo || dd->m_serverAccess != ServerAccess::WithAuthorization
|
||||
|| !dd->m_apiToken) {
|
||||
return SetupResult::StopWithSuccess; // Unauthorized access should have collect dashboard before
|
||||
}
|
||||
dashboardStorage->credential = "AxToken " + *dd->m_apiToken;
|
||||
dashboardStorage->url = QUrl(settings().server.dashboard);
|
||||
return SetupResult::Continue;
|
||||
};
|
||||
const auto onDeleteCredentialSetup = [dashboardStorage](CredentialQuery &credential) {
|
||||
if (dashboardStorage->dtoData) {
|
||||
dd->m_dashboardInfo = toDashboardInfo(*dashboardStorage);
|
||||
return SetupResult::StopWithSuccess;
|
||||
}
|
||||
dd->m_apiToken = {};
|
||||
MessageManager::writeFlashing(QString("Axivion: %1")
|
||||
.arg(Tr::tr("The stored ApiToken is not valid anymore, removing it.")));
|
||||
credential.setOperation(CredentialOperation::Delete);
|
||||
credential.setService(s_axivionKeychainService);
|
||||
credential.setKey(credentialKey());
|
||||
return SetupResult::Continue;
|
||||
};
|
||||
|
||||
return {
|
||||
Group {
|
||||
unauthorizedDashboardStorage,
|
||||
@@ -620,7 +644,7 @@ static Group authorizationRecipe()
|
||||
Group {
|
||||
passwordStorage,
|
||||
dashboardStorage,
|
||||
onGroupSetup(onDashboardGroupSetup),
|
||||
onGroupSetup(onPasswordGroupSetup),
|
||||
Group { // GET DashboardInfoDto
|
||||
finishAllAndSuccess,
|
||||
dtoRecipe(dashboardStorage)
|
||||
@@ -631,6 +655,13 @@ static Group authorizationRecipe()
|
||||
dtoRecipe(apiTokenStorage),
|
||||
CredentialQueryTask(onSetCredentialSetup, onSetCredentialDone, CallDoneIf::Error)
|
||||
}
|
||||
},
|
||||
Group {
|
||||
finishAllAndSuccess,
|
||||
dashboardStorage,
|
||||
onGroupSetup(onDashboardGroupSetup),
|
||||
dtoRecipe(dashboardStorage),
|
||||
CredentialQueryTask(onDeleteCredentialSetup)
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -671,27 +702,22 @@ Group dashboardInfoRecipe(const DashboardInfoHandler &handler)
|
||||
{
|
||||
const auto onSetup = [handler] {
|
||||
if (dd->m_dashboardInfo) {
|
||||
if (handler)
|
||||
handler(*dd->m_dashboardInfo);
|
||||
handler(*dd->m_dashboardInfo);
|
||||
return SetupResult::StopWithSuccess;
|
||||
}
|
||||
return SetupResult::Continue;
|
||||
};
|
||||
const auto onDone = [handler] {
|
||||
if (handler)
|
||||
handler(make_unexpected(QString("Error"))); // TODO: Collect error message in the storage.
|
||||
};
|
||||
|
||||
const auto resultHandler = [handler](const Dto::DashboardInfoDto &data) {
|
||||
dd->m_dashboardInfo = toDashboardInfo(settings().server.dashboard, data);
|
||||
if (handler)
|
||||
const auto onDone = [handler](DoneWith result) {
|
||||
if (result == DoneWith::Success && dd->m_dashboardInfo)
|
||||
handler(*dd->m_dashboardInfo);
|
||||
else
|
||||
handler(make_unexpected(QString("Error"))); // TODO: Collect error message in the storage.
|
||||
};
|
||||
|
||||
const Group root {
|
||||
onGroupSetup(onSetup), // Stops if cache exists.
|
||||
fetchDataRecipe<Dto::DashboardInfoDto>(settings().server.dashboard, resultHandler),
|
||||
onGroupDone(onDone, CallDoneIf::Error)
|
||||
authorizationRecipe(),
|
||||
onGroupDone(onDone)
|
||||
};
|
||||
return root;
|
||||
}
|
||||
@@ -770,7 +796,7 @@ void AxivionPluginPrivate::fetchProjectInfo(const QString &projectName)
|
||||
};
|
||||
|
||||
const Group root {
|
||||
dashboardInfoRecipe(),
|
||||
authorizationRecipe(),
|
||||
TaskTreeTask(onTaskTreeSetup)
|
||||
};
|
||||
m_taskTreeRunner.start(root);
|
||||
|
Reference in New Issue
Block a user