mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 03:18:07 +00:00
sso page to manually cancel sso connection (TODO: fix crash when global state not on and trying to get current account)
This commit is contained in:
parent
83675dd9bb
commit
dcd84a78ef
7 changed files with 172 additions and 6 deletions
|
|
@ -329,6 +329,9 @@ App::App(int &argc, char *argv[])
|
||||||
mEventCountNotifier = new EventCountNotifier(this);
|
mEventCountNotifier = new EventCountNotifier(this);
|
||||||
mDateUpdateTimer.start();
|
mDateUpdateTimer.start();
|
||||||
|
|
||||||
|
mOIDCRefreshTimer.setInterval(1000);
|
||||||
|
mOIDCRefreshTimer.setSingleShot(false);
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
exportDesktopFile();
|
exportDesktopFile();
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -384,7 +387,29 @@ void App::setSelf(QSharedPointer<App>(me)) {
|
||||||
mCoreModelConnection->makeConnectToModel(
|
mCoreModelConnection->makeConnectToModel(
|
||||||
&CoreModel::globalStateChanged,
|
&CoreModel::globalStateChanged,
|
||||||
[this](const std::shared_ptr<linphone::Core> &core, linphone::GlobalState gstate, const std::string &message) {
|
[this](const std::shared_ptr<linphone::Core> &core, linphone::GlobalState gstate, const std::string &message) {
|
||||||
mCoreModelConnection->invokeToCore([this, gstate] { setCoreStarted(gstate == linphone::GlobalState::On); });
|
mCoreModelConnection->invokeToCore([this, gstate] {
|
||||||
|
setCoreStarted(gstate == linphone::GlobalState::On);
|
||||||
|
if (gstate == linphone::GlobalState::Configuring) {
|
||||||
|
if (mMainWindow) {
|
||||||
|
QMetaObject::invokeMethod(mMainWindow, "openSSOPage", Qt::DirectConnection);
|
||||||
|
} else {
|
||||||
|
connect(
|
||||||
|
this, &App::mainWindowChanged, this,
|
||||||
|
[this] {
|
||||||
|
mCoreModelConnection->invokeToModel([this] {
|
||||||
|
auto gstate = CoreModel::getInstance()->getCore()->getGlobalState();
|
||||||
|
if (gstate == linphone::GlobalState::Configuring)
|
||||||
|
mCoreModelConnection->invokeToCore([this] {
|
||||||
|
if (mMainWindow)
|
||||||
|
QMetaObject::invokeMethod(mMainWindow, "openSSOPage",
|
||||||
|
Qt::DirectConnection);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
Qt::SingleShotConnection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
mCoreModelConnection->makeConnectToModel(&CoreModel::authenticationRequested, &App::onAuthenticationRequested);
|
mCoreModelConnection->makeConnectToModel(&CoreModel::authenticationRequested, &App::onAuthenticationRequested);
|
||||||
// Config error message
|
// Config error message
|
||||||
|
|
@ -425,7 +450,28 @@ void App::setSelf(QSharedPointer<App>(me)) {
|
||||||
// Synchronize state for because linphoneCore was ran before any connections.
|
// Synchronize state for because linphoneCore was ran before any connections.
|
||||||
mCoreModelConnection->invokeToModel([this]() {
|
mCoreModelConnection->invokeToModel([this]() {
|
||||||
auto state = CoreModel::getInstance()->getCore()->getGlobalState();
|
auto state = CoreModel::getInstance()->getCore()->getGlobalState();
|
||||||
mCoreModelConnection->invokeToCore([this, state] { setCoreStarted(state == linphone::GlobalState::On); });
|
mCoreModelConnection->invokeToCore([this, state] {
|
||||||
|
setCoreStarted(state == linphone::GlobalState::On);
|
||||||
|
if (state == linphone::GlobalState::Configuring) {
|
||||||
|
if (mMainWindow) {
|
||||||
|
QMetaObject::invokeMethod(mMainWindow, "openSSOPage", Qt::DirectConnection);
|
||||||
|
} else {
|
||||||
|
connect(
|
||||||
|
this, &App::mainWindowChanged, this,
|
||||||
|
[this] {
|
||||||
|
mCoreModelConnection->invokeToModel([this] {
|
||||||
|
auto gstate = CoreModel::getInstance()->getCore()->getGlobalState();
|
||||||
|
if (gstate == linphone::GlobalState::Configuring)
|
||||||
|
mCoreModelConnection->invokeToCore([this] {
|
||||||
|
if (mMainWindow)
|
||||||
|
QMetaObject::invokeMethod(mMainWindow, "openSSOPage", Qt::DirectConnection);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
Qt::SingleShotConnection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
mCoreModelConnection->makeConnectToModel(&CoreModel::unreadNotificationsChanged, [this] {
|
mCoreModelConnection->makeConnectToModel(&CoreModel::unreadNotificationsChanged, [this] {
|
||||||
|
|
@ -477,6 +523,33 @@ void App::setSelf(QSharedPointer<App>(me)) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
mCoreModelConnection->makeConnectToModel(&CoreModel::oidcRemainingTimeBeforeTimeoutChanged,
|
||||||
|
[this](int remainingTime) {
|
||||||
|
qDebug() << "App: oidc timeout changed";
|
||||||
|
mCoreModelConnection->invokeToCore([this, remainingTime] {
|
||||||
|
mRemainingTimeBeforeOidcTimeout = remainingTime;
|
||||||
|
emit remainingTimeBeforeOidcTimeoutChanged();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
mCoreModelConnection->makeConnectToCore(&App::lForceOidcTimeout, [this] {
|
||||||
|
qDebug() << "App: force oidc timeout";
|
||||||
|
mCoreModelConnection->invokeToModel([this] {
|
||||||
|
mOIDCRefreshTimer.stop();
|
||||||
|
emit CoreModel::getInstance()->forceOidcTimeout();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
mCoreModelConnection->makeConnectToModel(&CoreModel::timeoutTimerStarted, [this]() {
|
||||||
|
qDebug() << "App: oidc timeout changed";
|
||||||
|
mCoreModelConnection->invokeToCore([this] { mOIDCRefreshTimer.start(); });
|
||||||
|
});
|
||||||
|
mCoreModelConnection->makeConnectToModel(&CoreModel::timeoutTimerStopped, [this]() {
|
||||||
|
qDebug() << "App: oidc timeout changed";
|
||||||
|
mCoreModelConnection->invokeToCore([this] { mOIDCRefreshTimer.stop(); });
|
||||||
|
});
|
||||||
|
connect(&mOIDCRefreshTimer, &QTimer::timeout, this, [this]() {
|
||||||
|
mCoreModelConnection->invokeToModel([this] { CoreModel::getInstance()->refreshOidcRemainingTime(); });
|
||||||
|
});
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------
|
||||||
mCliModelConnection = SafeConnection<App, CliModel>::create(me, CliModel::getInstance());
|
mCliModelConnection = SafeConnection<App, CliModel>::create(me, CliModel::getInstance());
|
||||||
mCliModelConnection->makeConnectToCore(&App::receivedMessage, [this](int, const QByteArray &byteArray) {
|
mCliModelConnection->makeConnectToCore(&App::receivedMessage, [this](int, const QByteArray &byteArray) {
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,8 @@ class App : public SingleApplication, public AbstractObject {
|
||||||
Q_PROPERTY(QString sdkVersion READ getSdkVersion CONSTANT)
|
Q_PROPERTY(QString sdkVersion READ getSdkVersion CONSTANT)
|
||||||
Q_PROPERTY(ChatGui *currentChat READ getCurrentChat WRITE setCurrentChat NOTIFY currentChatChanged)
|
Q_PROPERTY(ChatGui *currentChat READ getCurrentChat WRITE setCurrentChat NOTIFY currentChatChanged)
|
||||||
Q_PROPERTY(QString localeAsString READ getLocaleAsString CONSTANT)
|
Q_PROPERTY(QString localeAsString READ getLocaleAsString CONSTANT)
|
||||||
|
Q_PROPERTY(int remainingTimeBeforeOidcTimeout MEMBER mRemainingTimeBeforeOidcTimeout NOTIFY
|
||||||
|
remainingTimeBeforeOidcTimeoutChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
App(int &argc, char *argv[]);
|
App(int &argc, char *argv[]);
|
||||||
|
|
@ -219,6 +221,8 @@ signals:
|
||||||
void chatsChanged();
|
void chatsChanged();
|
||||||
void callHistoryChanged();
|
void callHistoryChanged();
|
||||||
void localeChanged();
|
void localeChanged();
|
||||||
|
void lForceOidcTimeout();
|
||||||
|
void remainingTimeBeforeOidcTimeoutChanged();
|
||||||
// void executeCommand(QString command);
|
// void executeCommand(QString command);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -257,6 +261,8 @@ private:
|
||||||
QTimer mDateUpdateTimer;
|
QTimer mDateUpdateTimer;
|
||||||
QDate mCurrentDate;
|
QDate mCurrentDate;
|
||||||
float mScreenRatio = 1;
|
float mScreenRatio = 1;
|
||||||
|
QTimer mOIDCRefreshTimer;
|
||||||
|
int mRemainingTimeBeforeOidcTimeout = 0;
|
||||||
|
|
||||||
DECLARE_ABSTRACT_OBJECT
|
DECLARE_ABSTRACT_OBJECT
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -120,14 +120,14 @@ OIDCModel::OIDCModel(const std::shared_ptr<linphone::AuthInfo> &authInfo, QObjec
|
||||||
connect(&mOidc, &QOAuth2AuthorizationCodeFlow::statusChanged, [=](QAbstractOAuth::Status status) {
|
connect(&mOidc, &QOAuth2AuthorizationCodeFlow::statusChanged, [=](QAbstractOAuth::Status status) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case QAbstractOAuth::Status::Granted: {
|
case QAbstractOAuth::Status::Granted: {
|
||||||
mTimeout.stop();
|
stopTimeoutTimer();
|
||||||
//: Authentication granted
|
//: Authentication granted
|
||||||
emit statusChanged(tr("oidc_authentication_granted_message"));
|
emit statusChanged(tr("oidc_authentication_granted_message"));
|
||||||
emit authenticated();
|
emit authenticated();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QAbstractOAuth::Status::NotAuthenticated: {
|
case QAbstractOAuth::Status::NotAuthenticated: {
|
||||||
mTimeout.stop();
|
stopTimeoutTimer();
|
||||||
//: Not authenticated
|
//: Not authenticated
|
||||||
emit statusChanged(tr("oidc_authentication_not_authenticated_message"));
|
emit statusChanged(tr("oidc_authentication_not_authenticated_message"));
|
||||||
emit finished();
|
emit finished();
|
||||||
|
|
@ -149,7 +149,7 @@ OIDCModel::OIDCModel(const std::shared_ptr<linphone::AuthInfo> &authInfo, QObjec
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(&mOidc, &QOAuth2AuthorizationCodeFlow::requestFailed, [=](QAbstractOAuth::Error error) {
|
connect(&mOidc, &QOAuth2AuthorizationCodeFlow::requestFailed, [=](QAbstractOAuth::Error error) {
|
||||||
mTimeout.stop();
|
stopTimeoutTimer();
|
||||||
|
|
||||||
const QMetaObject metaObject = QAbstractOAuth::staticMetaObject;
|
const QMetaObject metaObject = QAbstractOAuth::staticMetaObject;
|
||||||
int index = metaObject.indexOfEnumerator("Error");
|
int index = metaObject.indexOfEnumerator("Error");
|
||||||
|
|
@ -183,10 +183,12 @@ OIDCModel::OIDCModel(const std::shared_ptr<linphone::AuthInfo> &authInfo, QObjec
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(&mOidc, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, [this](const QUrl &url) {
|
connect(&mOidc, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, [this](const QUrl &url) {
|
||||||
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
qDebug() << "Browser authentication url : " << url;
|
qDebug() << "Browser authentication url : " << url;
|
||||||
//: Requesting authorization from browser
|
//: Requesting authorization from browser
|
||||||
emit statusChanged(tr("oidc_authentication_request_auth_message"));
|
emit statusChanged(tr("oidc_authentication_request_auth_message"));
|
||||||
mTimeout.start();
|
mTimeout.start();
|
||||||
|
emit timeoutTimerStarted();
|
||||||
QDesktopServices::openUrl(url);
|
QDesktopServices::openUrl(url);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -261,6 +263,29 @@ OIDCModel::OIDCModel(const std::shared_ptr<linphone::AuthInfo> &authInfo, QObjec
|
||||||
connect(reply, &QNetworkReply::finished, this, &OIDCModel::openIdConfigReceived);
|
connect(reply, &QNetworkReply::finished, this, &OIDCModel::openIdConfigReceived);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OIDCModel::forceTimeout() {
|
||||||
|
lWarning() << log().arg("Froce timeout for OpenID connection.");
|
||||||
|
stopTimeoutTimer();
|
||||||
|
dynamic_cast<OAuthHttpServerReplyHandler *>(mOidc.replyHandler())->close();
|
||||||
|
CoreModel::getInstance()->getCore()->abortAuthentication(mAuthInfo);
|
||||||
|
//: Timeout: Not authenticated
|
||||||
|
emit statusChanged(tr("oidc_authentication_timeout_message"));
|
||||||
|
emit finished();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OIDCModel::isTimerRunning() const {
|
||||||
|
return mTimeout.isActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
int OIDCModel::getRemainingTimeBeforeTimeOut() {
|
||||||
|
return mTimeout.remainingTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OIDCModel::stopTimeoutTimer() {
|
||||||
|
mTimeout.stop();
|
||||||
|
emit timeoutTimerStopped();
|
||||||
|
}
|
||||||
|
|
||||||
void OIDCModel::openIdConfigReceived() {
|
void OIDCModel::openIdConfigReceived() {
|
||||||
auto reply = dynamic_cast<QNetworkReply *>(sender());
|
auto reply = dynamic_cast<QNetworkReply *>(sender());
|
||||||
auto document = QJsonDocument::fromJson(reply->readAll());
|
auto document = QJsonDocument::fromJson(reply->readAll());
|
||||||
|
|
|
||||||
|
|
@ -36,12 +36,18 @@ public:
|
||||||
|
|
||||||
void openIdConfigReceived();
|
void openIdConfigReceived();
|
||||||
void setBearers();
|
void setBearers();
|
||||||
|
void forceTimeout();
|
||||||
|
bool isTimerRunning() const;
|
||||||
|
int getRemainingTimeBeforeTimeOut();
|
||||||
|
void stopTimeoutTimer();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void authenticated();
|
void authenticated();
|
||||||
void requestFailed(const QString &error);
|
void requestFailed(const QString &error);
|
||||||
void statusChanged(const QString &status);
|
void statusChanged(const QString &status);
|
||||||
void finished();
|
void finished();
|
||||||
|
void timeoutTimerStarted();
|
||||||
|
void timeoutTimerStopped();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,14 @@ void CoreModel::setConfigPath(QString path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CoreModel::refreshOidcRemainingTime() {
|
||||||
|
for (auto &oidc : mOpenIdConnections) {
|
||||||
|
if (oidc && oidc->isTimerRunning()) {
|
||||||
|
emit oidcRemainingTimeBeforeTimeoutChanged(oidc->getRemainingTimeBeforeTimeOut());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
// PATHS
|
// PATHS
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
|
|
@ -402,7 +410,15 @@ void CoreModel::onAuthenticationRequested(const std::shared_ptr<linphone::Core>
|
||||||
<< realm << " at " << serverUrl;
|
<< realm << " at " << serverUrl;
|
||||||
QString key = username + '@' + realm + ' ' + serverUrl;
|
QString key = username + '@' + realm + ' ' + serverUrl;
|
||||||
if (mOpenIdConnections.contains(key)) mOpenIdConnections[key]->deleteLater();
|
if (mOpenIdConnections.contains(key)) mOpenIdConnections[key]->deleteLater();
|
||||||
mOpenIdConnections[key] = new OIDCModel(authInfo, this);
|
auto oidcModel = new OIDCModel(authInfo, this);
|
||||||
|
mOpenIdConnections[key] = oidcModel;
|
||||||
|
connect(oidcModel, &OIDCModel::timeoutTimerStarted, this, [this] {
|
||||||
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
|
emit timeoutTimerStarted();
|
||||||
|
qDebug() << "start refresh timer";
|
||||||
|
});
|
||||||
|
connect(oidcModel, &OIDCModel::timeoutTimerStopped, this, [this] { emit timeoutTimerStopped(); });
|
||||||
|
connect(this, &CoreModel::forceOidcTimeout, oidcModel, [this, oidcModel] { oidcModel->forceTimeout(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emit authenticationRequested(core, authInfo, method);
|
emit authenticationRequested(core, authInfo, method);
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,8 @@ public:
|
||||||
void start();
|
void start();
|
||||||
void setConfigPath(QString path);
|
void setConfigPath(QString path);
|
||||||
|
|
||||||
|
void refreshOidcRemainingTime();
|
||||||
|
|
||||||
QString getFetchConfig(QString filePath, bool *error);
|
QString getFetchConfig(QString filePath, bool *error);
|
||||||
void useFetchConfig(QString filePath);
|
void useFetchConfig(QString filePath);
|
||||||
bool setFetchConfig(QString filePath);
|
bool setFetchConfig(QString filePath);
|
||||||
|
|
@ -93,6 +95,10 @@ signals:
|
||||||
void enabledLdapAddressBookSaved();
|
void enabledLdapAddressBookSaved();
|
||||||
void magicSearchResultReceived(QString filter);
|
void magicSearchResultReceived(QString filter);
|
||||||
void messageReadInChatRoom(std::shared_ptr<linphone::ChatRoom> chatRoom);
|
void messageReadInChatRoom(std::shared_ptr<linphone::ChatRoom> chatRoom);
|
||||||
|
void oidcRemainingTimeBeforeTimeoutChanged(int remainingTime);
|
||||||
|
void forceOidcTimeout();
|
||||||
|
void timeoutTimerStarted();
|
||||||
|
void timeoutTimerStopped();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString mConfigPath;
|
QString mConfigPath;
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,10 @@ AbstractWindow {
|
||||||
mainWindowStackView.replace(loginPage)
|
mainWindowStackView.replace(loginPage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openSSOPage() {
|
||||||
|
mainWindowStackView.replace(ssoPage)
|
||||||
|
}
|
||||||
|
|
||||||
function scheduleMeeting(subject, addresses) {
|
function scheduleMeeting(subject, addresses) {
|
||||||
openMainPage()
|
openMainPage()
|
||||||
mainWindowStackView.currentItem.scheduleMeeting(subject, addresses)
|
mainWindowStackView.currentItem.scheduleMeeting(subject, addresses)
|
||||||
|
|
@ -181,6 +185,36 @@ AbstractWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Component {
|
||||||
|
id: ssoPage
|
||||||
|
Rectangle {
|
||||||
|
color: DefaultStyle.grey_0
|
||||||
|
Image {
|
||||||
|
id: logoImage
|
||||||
|
anchors.centerIn: parent
|
||||||
|
source: AppIcons.splashscreenLogo
|
||||||
|
sourceSize.width: Utils.getSizeWithScreenRatio(395)
|
||||||
|
sourceSize.height: Utils.getSizeWithScreenRatio(395)
|
||||||
|
width: Utils.getSizeWithScreenRatio(395)
|
||||||
|
height: Utils.getSizeWithScreenRatio(395)
|
||||||
|
}
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.top: logoImage.bottom
|
||||||
|
anchors.topMargin: Utils.getSizeWithScreenRatio(20)
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
Text {
|
||||||
|
text: "Trying to connect to single sign on on web page ..."
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: UtilsCpp.formatDuration(AppCpp.remainingTimeBeforeOidcTimeout)
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: qsTr("cancel")
|
||||||
|
onClicked: AppCpp.lForceOidcTimeout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Component {
|
Component {
|
||||||
id: loginPage
|
id: loginPage
|
||||||
LoginPage {
|
LoginPage {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue