Skip to content
Permalink
Browse files

[oauth2] Handle the opening and closing of browser through the networ…

…k authentication

handler
  • Loading branch information
nirvn committed Apr 22, 2021
1 parent e3f1629 commit 584283ddaa7cf8d180ce17599c89b3954cb9e2ee
@@ -319,6 +319,20 @@ The contents of the reply will be returned after the request is completed or an
.. seealso:: :py:func:`blockingGet`

.. versionadded:: 3.6
%End

void requestAuthOpenBrowser( const QUrl &url ) const;
%Docstring
Forwards an external browser login ``url`` opening request to the authentication handler.

.. versionadded:: 3.20
%End

void requestAuthCloseBrowser() const;
%Docstring
Forwards an external browser login closure equest to the authentication handler.

.. versionadded:: 3.20
%End

signals:
@@ -22,6 +22,7 @@
#include "qgscredentials.h"

#include <QAuthenticator>
#include <QDesktopServices>

void QgsAppAuthRequestHandler::handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth )
{
@@ -75,3 +76,27 @@ void QgsAppAuthRequestHandler::handleAuthRequest( QNetworkReply *reply, QAuthent
auth->setUser( username );
auth->setPassword( password );
}

void QgsAppAuthRequestHandler::handleAuthRequestOpenBrowser( const QUrl &url )
{
QDesktopServices::openUrl( url );
}

void QgsAppAuthRequestHandler::handleAuthRequestCloseBrowser()
{
// Bring focus back to QGIS app
if ( qApp )
{
const QList<QWidget *> topWidgets = QgsApplication::topLevelWidgets();
for ( QWidget *topWidget : topWidgets )
{
if ( topWidget->objectName() == QLatin1String( "MainWindow" ) )
{
topWidget->raise();
topWidget->activateWindow();
topWidget->show();
break;
}
}
}
}
@@ -22,7 +22,9 @@ class QgsAppAuthRequestHandler : public QgsNetworkAuthenticationHandler

public:

void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth ) override;
void handleAuthRequestOpenBrowser( const QUrl &url ) override;
void handleAuthRequestCloseBrowser() override;

};

@@ -32,7 +32,6 @@

#include <QDateTime>
#include <QInputDialog>
#include <QDesktopServices>
#include <QDir>
#include <QEventLoop>
#include <QPointer>
@@ -180,8 +179,6 @@ bool QgsAuthOAuth2Method::updateNetworkRequest( QNetworkRequest &request, const
connect( o2, &QgsO2::linkedChanged, this, &QgsAuthOAuth2Method::onLinkedChanged, Qt::UniqueConnection );
connect( o2, &QgsO2::linkingFailed, this, &QgsAuthOAuth2Method::onLinkingFailed, Qt::UniqueConnection );
connect( o2, &QgsO2::linkingSucceeded, this, &QgsAuthOAuth2Method::onLinkingSucceeded, Qt::UniqueConnection );
connect( o2, &QgsO2::openBrowser, this, &QgsAuthOAuth2Method::onOpenBrowser, Qt::UniqueConnection );
connect( o2, &QgsO2::closeBrowser, this, &QgsAuthOAuth2Method::onCloseBrowser, Qt::UniqueConnection );
connect( o2, &QgsO2::getAuthCode, this, &QgsAuthOAuth2Method::onAuthCode, Qt::UniqueConnection );
connect( this, &QgsAuthOAuth2Method::setAuthCode, o2, &QgsO2::onSetAuthCode, Qt::UniqueConnection );
//qRegisterMetaType<QNetworkReply::NetworkError>( QStringLiteral( "QNetworkReply::NetworkError" )) // for Qt::QueuedConnection, if needed;
@@ -375,39 +372,6 @@ void QgsAuthOAuth2Method::onLinkingSucceeded()
}
}

void QgsAuthOAuth2Method::onOpenBrowser( const QUrl &url )
{
// Open a web browser or a web view with the given URL.
// The user will interact with this browser window to
// enter login name, password, and authorize your application
// to access the Twitter account
QgsDebugMsgLevel( QStringLiteral( "Open browser requested %1" ), 2 );

QDesktopServices::openUrl( url );
}

void QgsAuthOAuth2Method::onCloseBrowser()
{
// Close the browser window opened in openBrowser()
QgsDebugMsgLevel( QStringLiteral( "Close browser requested %1" ), 2 );

// Bring focus back to QGIS app
if ( qApp )
{
const QList<QWidget *> widgets = QgsApplication::topLevelWidgets();
for ( QWidget *topwdgt : widgets )
{
if ( topwdgt->objectName() == QLatin1String( "MainWindow" ) )
{
topwdgt->raise();
topwdgt->activateWindow();
topwdgt->show();
break;
}
}
}
}

void QgsAuthOAuth2Method::onReplyFinished()
{
QgsMessageLog::logMessage( tr( "Network reply finished" ), AUTH_METHOD_KEY, Qgis::MessageLevel::Info );
@@ -78,12 +78,6 @@ class QgsAuthOAuth2Method : public QgsAuthMethod
//! Triggered when linking operation succeeded
void onLinkingSucceeded();

//! Triggered when the browser needs to be opened at \a url
void onOpenBrowser( const QUrl &url );

//! Triggered on browser close
void onCloseBrowser();

//! Triggered on reply finished
void onReplyFinished();

@@ -208,7 +208,7 @@ void QgsO2::link()
query.setQueryItems( parameters );
url.setQuery( query );
QgsDebugMsgLevel( QStringLiteral( "QgsO2::link: Emit openBrowser %1" ).arg( url.toString() ), 4 );
emit openBrowser( url );
QgsNetworkAccessManager::instance()->requestAuthOpenBrowser( url );
if ( !mIsLocalHost )
{
emit getAuthCode();
@@ -259,7 +259,7 @@ void QgsO2::setState( const QString & )
void QgsO2::onVerificationReceived( QMap<QString, QString> response )
{
QgsDebugMsgLevel( QStringLiteral( "QgsO2::onVerificationReceived: Emitting closeBrowser()" ), 4 );
emit closeBrowser();
QgsNetworkAccessManager::instance()->requestAuthCloseBrowser();

if ( mIsLocalHost )
{
@@ -463,6 +463,26 @@ void QgsNetworkAccessManager::onAuthRequired( QNetworkReply *reply, QAuthenticat
}
}

void QgsNetworkAccessManager::requestAuthOpenBrowser( const QUrl &url ) const
{
if ( this != sMainNAM )
{
sMainNAM->requestAuthOpenBrowser( url );
return;
}
mAuthHandler->handleAuthRequestOpenBrowser( url );
}

void QgsNetworkAccessManager::requestAuthCloseBrowser() const
{
if ( this != sMainNAM )
{
sMainNAM->requestAuthCloseBrowser();
return;
}
mAuthHandler->handleAuthRequestCloseBrowser();
}

void QgsNetworkAccessManager::handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth )
{
mAuthHandler->handleAuthRequest( reply, auth );
@@ -714,3 +734,14 @@ void QgsNetworkAuthenticationHandler::handleAuthRequest( QNetworkReply *reply, Q
Q_UNUSED( reply )
QgsDebugMsg( QStringLiteral( "Network reply required authentication, but no handler was in place to provide this authentication request while accessing the URL:\n%1" ).arg( reply->request().url().toString() ) );
}

void QgsNetworkAuthenticationHandler::handleAuthRequestOpenBrowser( const QUrl &url )
{
Q_UNUSED( url )
QgsDebugMsg( QStringLiteral( "Network authentication required external browser to open URL %1, but no handler was in place" ).arg( url.toString() ) );
}

void QgsNetworkAuthenticationHandler::handleAuthRequestCloseBrowser()
{
QgsDebugMsg( QStringLiteral( "Network authentication required external browser closed, but no handler was in place" ) );
}
@@ -227,6 +227,20 @@ class CORE_EXPORT QgsNetworkAuthenticationHandler
*/
virtual void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );

/**
* Called to initiate a network authentication through external browser \a url.
*
* \since QGIS 3.20
*/
virtual void handleAuthRequestOpenBrowser( const QUrl &url );

/**
* Called to terminate a network authentication through external browser.
*
* \since QGIS 3.20
*/
virtual void handleAuthRequestCloseBrowser();

};
#endif

@@ -499,6 +513,20 @@ class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager
*/
static QgsNetworkReplyContent blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr );

/**
* Forwards an external browser login \a url opening request to the authentication handler.
*
* \since QGIS 3.20
*/
void requestAuthOpenBrowser( const QUrl &url ) const;

/**
* Forwards an external browser login closure equest to the authentication handler.
*
* \since QGIS 3.20
*/
void requestAuthCloseBrowser() const;

signals:

/**

0 comments on commit 584283d

Please sign in to comment.