mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-04-17 20:08:28 +00:00
add debug for sso issue and display error on request failed
This commit is contained in:
parent
91534868b6
commit
e23afaf0de
5 changed files with 73 additions and 24 deletions
|
|
@ -368,6 +368,7 @@ void App::setSelf(QSharedPointer<App>(me)) {
|
|||
bool askForConfirmation) {
|
||||
mCoreModelConnection->invokeToCore([this, path, askForConfirmation]() {
|
||||
auto apply = [this, path] {
|
||||
lInfo() << log().arg("Apply fetch config");
|
||||
mCoreModelConnection->invokeToModel([this, path]() { CoreModel::getInstance()->setFetchConfig(path); });
|
||||
};
|
||||
auto callback = [this, path, askForConfirmation]() {
|
||||
|
|
@ -385,9 +386,10 @@ void App::setSelf(QSharedPointer<App>(me)) {
|
|||
QMetaObject::invokeMethod(getMainWindow(), "showConfirmationPopup", QVariant::fromValue(obj));
|
||||
};
|
||||
if (!getMainWindow()) { // Delay
|
||||
if (askForConfirmation)
|
||||
if (askForConfirmation) {
|
||||
lInfo() << log() << "App wants confirmation before applying config, wait for main window to open";
|
||||
connect(this, &App::mainWindowChanged, this, callback, Qt::SingleShotConnection);
|
||||
else connect(this, &App::mainWindowChanged, this, apply, Qt::SingleShotConnection);
|
||||
} else connect(this, &App::mainWindowChanged, this, apply, Qt::SingleShotConnection);
|
||||
} else {
|
||||
if (askForConfirmation) callback();
|
||||
else apply();
|
||||
|
|
@ -398,6 +400,7 @@ void App::setSelf(QSharedPointer<App>(me)) {
|
|||
&CoreModel::globalStateChanged,
|
||||
[this](const std::shared_ptr<linphone::Core> &core, linphone::GlobalState gstate, const std::string &message) {
|
||||
mCoreModelConnection->invokeToCore([this, gstate] {
|
||||
lInfo() << log().arg("Core global state changed :") << (int)gstate;
|
||||
setCoreStarted(gstate == linphone::GlobalState::On);
|
||||
if (gstate == linphone::GlobalState::Configuring) {
|
||||
if (mMainWindow) {
|
||||
|
|
@ -465,6 +468,7 @@ void App::setSelf(QSharedPointer<App>(me)) {
|
|||
// Synchronize state for because linphoneCore was ran before any connections.
|
||||
mCoreModelConnection->invokeToModel([this]() {
|
||||
auto state = CoreModel::getInstance()->getCore()->getGlobalState();
|
||||
lInfo() << log().arg("Start app, core global state =") << (int)state;
|
||||
mCoreModelConnection->invokeToCore([this, state] {
|
||||
setCoreStarted(state == linphone::GlobalState::On);
|
||||
if (state == linphone::GlobalState::Configuring) {
|
||||
|
|
@ -547,6 +551,10 @@ void App::setSelf(QSharedPointer<App>(me)) {
|
|||
emit remainingTimeBeforeOidcTimeoutChanged();
|
||||
});
|
||||
});
|
||||
mCoreModelConnection->makeConnectToModel(&CoreModel::oidcRequestFailed, [this](const QString &error) {
|
||||
mCoreModelConnection->invokeToCore(
|
||||
[this, error] { Utils::showInformationPopup("info_popup_error_title", error, false); });
|
||||
});
|
||||
mCoreModelConnection->makeConnectToCore(&App::lForceOidcTimeout, [this] {
|
||||
qDebug() << "App: force oidc timeout";
|
||||
mCoreModelConnection->invokeToModel([this] { emit CoreModel::getInstance()->forceOidcTimeout(); });
|
||||
|
|
@ -1421,6 +1429,7 @@ void App::onAuthenticationRequested(const std::shared_ptr<linphone::Core> &core,
|
|||
const std::shared_ptr<linphone::AuthInfo> &authInfo,
|
||||
linphone::AuthMethod method) {
|
||||
bool authInfoIsInAccounts = false;
|
||||
lInfo() << log().arg("onAuthenticationRequested, method =") << (int)method;
|
||||
if (authInfo) {
|
||||
for (auto &account : core->getAccountList()) {
|
||||
if (!account) continue;
|
||||
|
|
|
|||
|
|
@ -49,12 +49,12 @@ QString OAuthHttpServerReplyHandler::callback() const {
|
|||
|
||||
OIDCModel::OIDCModel(const std::shared_ptr<linphone::AuthInfo> &authInfo, QObject *parent) {
|
||||
auto port = CoreModel::getInstance()->getCore()->getConfig()->getInt("app", "oidc_redirect_uri_port", 0);
|
||||
qDebug() << "OIDC Redirect URI Port set to [" << port << "]";
|
||||
lInfo() << "OIDC Redirect URI Port set to [" << port << "]";
|
||||
auto replyHandler = new OAuthHttpServerReplyHandler(port, this);
|
||||
if (!replyHandler->isListening()) {
|
||||
lWarning() << log().arg("OAuthHttpServerReplyHandler is not listening on port") << port;
|
||||
emit requestFailed(tr("OAuthHttpServerReplyHandler is not listening"));
|
||||
emit finished();
|
||||
// emit finished();
|
||||
return;
|
||||
}
|
||||
mAuthInfo = authInfo;
|
||||
|
|
@ -72,12 +72,12 @@ OIDCModel::OIDCModel(const std::shared_ptr<linphone::AuthInfo> &authInfo, QObjec
|
|||
}
|
||||
mOidc.setClientIdentifier(clientid);
|
||||
mAuthInfo->setClientId(clientid.toStdString());
|
||||
qDebug() << "OIDC Client ID set to [" << clientid << "]";
|
||||
lInfo() << "OIDC Client ID set to [" << clientid << "]";
|
||||
|
||||
// find an auth info from LinphoneCore where username = clientid
|
||||
auto clientSecret = CoreModel::getInstance()->getCore()->findAuthInfo("", clientid.toStdString(), "");
|
||||
if (clientSecret != nullptr) {
|
||||
qDebug() << "client secret found for client id [" << clientid << "]";
|
||||
lInfo() << "client secret found for client id [" << clientid << "]";
|
||||
mOidc.setClientIdentifierSharedKey(clientSecret->getPassword().c_str());
|
||||
}
|
||||
|
||||
|
|
@ -121,6 +121,7 @@ OIDCModel::OIDCModel(const std::shared_ptr<linphone::AuthInfo> &authInfo, QObjec
|
|||
connect(&mOidc, &QOAuth2AuthorizationCodeFlow::statusChanged, [=](QAbstractOAuth::Status status) {
|
||||
switch (status) {
|
||||
case QAbstractOAuth::Status::Granted: {
|
||||
lInfo() << log().arg("Authentication granted");
|
||||
stopTimeoutTimer();
|
||||
//: Authentication granted
|
||||
emit statusChanged(tr("oidc_authentication_granted_message"));
|
||||
|
|
@ -128,6 +129,7 @@ OIDCModel::OIDCModel(const std::shared_ptr<linphone::AuthInfo> &authInfo, QObjec
|
|||
break;
|
||||
}
|
||||
case QAbstractOAuth::Status::NotAuthenticated: {
|
||||
lInfo() << log().arg("Not authenticated");
|
||||
stopTimeoutTimer();
|
||||
//: Not authenticated
|
||||
emit statusChanged(tr("oidc_authentication_not_authenticated_message"));
|
||||
|
|
@ -135,11 +137,13 @@ OIDCModel::OIDCModel(const std::shared_ptr<linphone::AuthInfo> &authInfo, QObjec
|
|||
break;
|
||||
}
|
||||
case QAbstractOAuth::Status::RefreshingToken: {
|
||||
lInfo() << log().arg("Refreshing token");
|
||||
//: Refreshing token
|
||||
emit statusChanged(tr("oidc_authentication_refresh_message"));
|
||||
break;
|
||||
}
|
||||
case QAbstractOAuth::Status::TemporaryCredentialsReceived: {
|
||||
lInfo() << log().arg("Temporary credentials received");
|
||||
//: Temporary credentials received
|
||||
emit statusChanged(tr("oidc_authentication_temporary_credentials_message"));
|
||||
break;
|
||||
|
|
@ -158,22 +162,27 @@ OIDCModel::OIDCModel(const std::shared_ptr<linphone::AuthInfo> &authInfo, QObjec
|
|||
lWarning() << log().arg("RequestFailed:") << metaEnum.valueToKey(static_cast<int>(error));
|
||||
switch (error) {
|
||||
case QAbstractOAuth::Error::NetworkError:
|
||||
lWarning() << log().arg("Network error");
|
||||
//: Network error
|
||||
emit requestFailed(tr("oidc_authentication_network_error"));
|
||||
break;
|
||||
case QAbstractOAuth::Error::ServerError:
|
||||
lWarning() << log().arg("Server error");
|
||||
//: Server error
|
||||
emit requestFailed(tr("oidc_authentication_server_error"));
|
||||
break;
|
||||
case QAbstractOAuth::Error::OAuthTokenNotFoundError:
|
||||
lWarning() << log().arg("OAuth token not found");
|
||||
//: OAuth token not found
|
||||
emit requestFailed(tr("oidc_authentication_token_not_found_error"));
|
||||
break;
|
||||
case QAbstractOAuth::Error::OAuthTokenSecretNotFoundError:
|
||||
lWarning() << log().arg("OAuth token secret not found");
|
||||
//: OAuth token secret not found
|
||||
emit requestFailed(tr("oidc_authentication_token_secret_not_found_error"));
|
||||
break;
|
||||
case QAbstractOAuth::Error::OAuthCallbackNotVerified:
|
||||
lWarning() << log().arg("OAuth callback not verified");
|
||||
//: OAuth callback not verified
|
||||
emit requestFailed(tr("oidc_authentication_callback_not_verified_error"));
|
||||
break;
|
||||
|
|
@ -185,7 +194,7 @@ OIDCModel::OIDCModel(const std::shared_ptr<linphone::AuthInfo> &authInfo, QObjec
|
|||
|
||||
connect(&mOidc, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, [this](const QUrl &url) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
qDebug() << "Browser authentication url : " << url;
|
||||
lInfo() << "Browser authentication url : " << url;
|
||||
//: Requesting authorization from browser
|
||||
emit statusChanged(tr("oidc_authentication_request_auth_message"));
|
||||
mTimeout.start();
|
||||
|
|
@ -222,7 +231,7 @@ OIDCModel::OIDCModel(const std::shared_ptr<linphone::AuthInfo> &authInfo, QObjec
|
|||
mIdToken.clear();
|
||||
lWarning() << "No ID Token or Access Token found in the tokens.";
|
||||
emit requestFailed(tr("oidc_authentication_no_token_found_error"));
|
||||
emit finished();
|
||||
// emit finished();
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
|
@ -258,9 +267,9 @@ OIDCModel::OIDCModel(const std::shared_ptr<linphone::AuthInfo> &authInfo, QObjec
|
|||
});
|
||||
|
||||
connect(this, &OIDCModel::finished, this, &OIDCModel::deleteLater);
|
||||
|
||||
auto url = QUrl(Utils::coreStringToAppString(authInfo->getAuthorizationServer()));
|
||||
url.setPath(url.path() + OIDCWellKnown);
|
||||
lInfo() << log().arg("Get request") << url;
|
||||
QNetworkRequest request(url);
|
||||
auto reply = mOidc.networkAccessManager()->get(request);
|
||||
connect(reply, &QNetworkReply::finished, this, &OIDCModel::openIdConfigReceived);
|
||||
|
|
@ -290,9 +299,17 @@ void OIDCModel::stopTimeoutTimer() {
|
|||
}
|
||||
|
||||
void OIDCModel::openIdConfigReceived() {
|
||||
lInfo() << log().arg("OpenID config received");
|
||||
auto reply = dynamic_cast<QNetworkReply *>(sender());
|
||||
lInfo() << log().arg("Reply :") << reply->readAll();
|
||||
auto document = QJsonDocument::fromJson(reply->readAll());
|
||||
if (document.isNull()) return;
|
||||
if (document.isNull()) {
|
||||
lWarning() << log().arg("Reply is empty");
|
||||
//: OIDC reply is empty !
|
||||
emit requestFailed(tr("oidc_authentication_empty_reply_error"));
|
||||
// emit finished();
|
||||
return;
|
||||
}
|
||||
auto rootArray = document.toVariant().toMap();
|
||||
if (rootArray.contains("authorization_endpoint")) {
|
||||
mOidc.setAuthorizationUrl(QUrl(rootArray["authorization_endpoint"].toString()));
|
||||
|
|
@ -300,10 +317,11 @@ void OIDCModel::openIdConfigReceived() {
|
|||
lWarning() << log().arg("No authorization endpoint found in OpenID configuration");
|
||||
//: No authorization endpoint found in OpenID configuration
|
||||
emit requestFailed(tr("oidc_authentication_no_auth_found_in_config_error"));
|
||||
emit finished();
|
||||
// emit finished();
|
||||
return;
|
||||
}
|
||||
if (rootArray.contains("token_endpoint")) {
|
||||
lInfo() << log().arg("Set token url %1").arg(rootArray["token_endpoint"].toString());
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
|
||||
mOidc.setTokenUrl(QUrl(rootArray["token_endpoint"].toString()));
|
||||
#else
|
||||
|
|
@ -315,9 +333,10 @@ void OIDCModel::openIdConfigReceived() {
|
|||
lWarning() << log().arg("No token endpoint found in OpenID configuration");
|
||||
//: No token endpoint found in OpenID configuration
|
||||
emit requestFailed(tr("oidc_authentication_no_token_found_in_config_error"));
|
||||
emit finished();
|
||||
// emit finished();
|
||||
return;
|
||||
}
|
||||
lInfo() << log().arg("Grant open id config");
|
||||
mOidc.grant();
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
|
@ -325,7 +344,7 @@ void OIDCModel::openIdConfigReceived() {
|
|||
void OIDCModel::setBearers() {
|
||||
auto expiration = QDateTime::currentDateTime().secsTo(mOidc.expirationAt());
|
||||
auto timeT = mOidc.expirationAt().toSecsSinceEpoch();
|
||||
qDebug() << "Authenticated for " << expiration << "s";
|
||||
lInfo() << "Authenticated for " << expiration << "s";
|
||||
|
||||
auto accessBearer = linphone::Factory::get()->createBearerToken(Utils::appStringToCoreString(idToken()), timeT);
|
||||
mAuthInfo->setAccessToken(accessBearer);
|
||||
|
|
|
|||
|
|
@ -128,12 +128,17 @@ void CliModel::cliShow(QHash<QString, QString> args) {
|
|||
}
|
||||
|
||||
void CliModel::cliFetchConfig(QHash<QString, QString> args) {
|
||||
lInfo() << log().arg("Run fetch-config function");
|
||||
if (args.contains("fetch-config")) {
|
||||
if (CoreModel::getInstance()->getCore()->getGlobalState() != linphone::GlobalState::On)
|
||||
if (CoreModel::getInstance()->getCore()->getGlobalState() != linphone::GlobalState::On) {
|
||||
lInfo() << log().arg("Global state is not on, wait for change of state to use config");
|
||||
connect(
|
||||
CoreModel::getInstance().get(), &CoreModel::globalStateChanged, this,
|
||||
[this, args]() { cliFetchConfig(args); }, Qt::SingleShotConnection);
|
||||
else CoreModel::getInstance()->useFetchConfig(args["fetch-config"], false);
|
||||
} else {
|
||||
lInfo() << log().arg("Global state is on, use config");
|
||||
CoreModel::getInstance()->useFetchConfig(args["fetch-config"], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +245,7 @@ void CliModel::Command::execute(QHash<QString, QString> &args, CliModel *parent)
|
|||
if (!mGenericArguments) { // Check arguments validity.
|
||||
for (const auto &argName : args.keys()) {
|
||||
if (!mArgsScheme.contains(argName)) {
|
||||
qWarning()
|
||||
lWarning()
|
||||
<< QStringLiteral("Command with invalid argument: `%1 (%2)`.").arg(mFunctionName).arg(argName);
|
||||
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -210,13 +210,14 @@ void CoreModel::setPathAfterStart() {
|
|||
|
||||
QString CoreModel::getFetchConfig(QString filePath, bool *error) {
|
||||
*error = false;
|
||||
lInfo() << log().arg("Get config %1").arg(filePath);
|
||||
if (!filePath.isEmpty()) {
|
||||
if (QUrl(filePath).isRelative()) { // this is a file path
|
||||
filePath = Paths::getConfigFilePath(filePath, false);
|
||||
if (!filePath.isEmpty()) filePath = "file://" + filePath;
|
||||
}
|
||||
if (filePath.isEmpty()) {
|
||||
qWarning() << "Remote provisioning cannot be retrieved. Command have been cleaned";
|
||||
lWarning() << "Remote provisioning path cannot be retrieved. Command have been cleaned";
|
||||
Utils::showInformationPopup(tr("info_popup_error_title"),
|
||||
//: "Remote provisioning cannot be retrieved"
|
||||
tr("fetching_config_failed_error_message"), false);
|
||||
|
|
@ -229,23 +230,28 @@ QString CoreModel::getFetchConfig(QString filePath, bool *error) {
|
|||
void CoreModel::useFetchConfig(QString filePath, bool askForConfirmation) {
|
||||
bool error = false;
|
||||
filePath = getFetchConfig(filePath, &error);
|
||||
lInfo() << log().arg("Use fetch config");
|
||||
if (!error && !filePath.isEmpty()) {
|
||||
|
||||
if (mCore && mCore->getGlobalState() == linphone::GlobalState::On) {
|
||||
// TODO
|
||||
// if (mSettings->getAutoApplyProvisioningConfigUriHandlerEnabled()) setFetchConfig(filePath); else
|
||||
lInfo() << log().arg("Request fetch config");
|
||||
emit requestFetchConfig(filePath, askForConfirmation);
|
||||
} else {
|
||||
lInfo() << log().arg("Global state is off, wait for requesting fetch config");
|
||||
connect(
|
||||
this, &CoreModel::globalStateChanged, this, [filePath, this]() { useFetchConfig(filePath); },
|
||||
this, &CoreModel::globalStateChanged, this,
|
||||
[filePath, askForConfirmation, this]() { useFetchConfig(filePath, askForConfirmation); },
|
||||
Qt::SingleShotConnection);
|
||||
}
|
||||
} else {
|
||||
lWarning() << log().arg("Could not get file path for fetching config, return");
|
||||
}
|
||||
}
|
||||
|
||||
bool CoreModel::setFetchConfig(QString filePath) {
|
||||
bool fetched = false;
|
||||
qDebug() << "setFetchConfig with " << filePath;
|
||||
lInfo() << "setFetchConfig with " << filePath;
|
||||
if (!filePath.isEmpty()) {
|
||||
if (mCore) {
|
||||
filePath.replace('\\', '/');
|
||||
|
|
@ -254,8 +260,11 @@ bool CoreModel::setFetchConfig(QString filePath) {
|
|||
}
|
||||
}
|
||||
if (!fetched) {
|
||||
qWarning() << "Remote provisionning cannot be retrieved. Command have been cleaned";
|
||||
} else emit requestRestart();
|
||||
lWarning() << "Remote provisionning cannot be retrieved. Command have been cleaned";
|
||||
} else {
|
||||
lInfo() << "Remote provisionning has been retrieved. Restart";
|
||||
emit requestRestart();
|
||||
}
|
||||
return fetched;
|
||||
}
|
||||
|
||||
|
|
@ -411,8 +420,8 @@ void CoreModel::onAuthenticationRequested(const std::shared_ptr<linphone::Core>
|
|||
auto username = Utils::coreStringToAppString(authInfo->getUsername());
|
||||
auto realm = Utils::coreStringToAppString(authInfo->getRealm());
|
||||
if (!serverUrl.isEmpty()) {
|
||||
qDebug() << "onAuthenticationRequested for Bearer. Initialize OpenID connection for " << username << "@"
|
||||
<< realm << " at " << serverUrl;
|
||||
lInfo() << "onAuthenticationRequested for Bearer. Initialize OpenID connection for " << username << "@"
|
||||
<< realm << " at " << serverUrl;
|
||||
QString key = username + '@' + realm + ' ' + serverUrl;
|
||||
if (mOpenIdConnections.contains(key)) mOpenIdConnections[key]->deleteLater();
|
||||
auto oidcModel = new OIDCModel(authInfo, this);
|
||||
|
|
@ -422,6 +431,12 @@ void CoreModel::onAuthenticationRequested(const std::shared_ptr<linphone::Core>
|
|||
emit timeoutTimerStarted();
|
||||
qDebug() << "start refresh timer";
|
||||
});
|
||||
connect(oidcModel, &OIDCModel::requestFailed, this, [this, oidcModel](const QString &error) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
lWarning() << log().arg("Request failed") << error;
|
||||
emit oidcRequestFailed(error);
|
||||
oidcModel->forceTimeout();
|
||||
});
|
||||
if (oidcModel->isTimerRunning()) {
|
||||
emit timeoutTimerStarted();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ signals:
|
|||
void messageReadInChatRoom(std::shared_ptr<linphone::ChatRoom> chatRoom);
|
||||
void oidcRemainingTimeBeforeTimeoutChanged(int remainingTime);
|
||||
void forceOidcTimeout();
|
||||
void oidcRequestFailed(const QString &error);
|
||||
void timeoutTimerStarted();
|
||||
void timeoutTimerStopped();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue