From 73041de9563c9a973d1b5394c6e5520a7d799980 Mon Sep 17 00:00:00 2001 From: Christian Lohmaier Date: Tue, 16 Feb 2021 14:07:34 +0100 Subject: tdf#101630 - gdrive support w/oAuth and Drive API v3 LibreOffice is only using drive.file scope, so can only see files it owns/that were created by LibreOffice. In addition, also store the refresh token in LO's password-store if the user enabled persistent storage, removing the need to to the copy'n'paste dance to grant access each time LO is launched. related tdf#115643 also store the refresh token for onedrive consolidate the fallback-auth provides for onedrive/gdrive into one, they are all the same login in browser, then copy code method that ultimately should be changed to having LO listen on local port for the code Change-Id: I97e3843682c302d2884e35ece6e72bc3a07e2539 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119572 Tested-by: Jenkins Reviewed-by: Christian Lohmaier --- ucb/source/ucp/cmis/auth_provider.cxx | 130 +++++++++++++++++++++++----------- 1 file changed, 89 insertions(+), 41 deletions(-) (limited to 'ucb/source/ucp/cmis/auth_provider.cxx') diff --git a/ucb/source/ucp/cmis/auth_provider.cxx b/ucb/source/ucp/cmis/auth_provider.cxx index 5c2ded12986e..05a8846a11a7 100644 --- a/ucb/source/ucp/cmis/auth_provider.cxx +++ b/ucb/source/ucp/cmis/auth_provider.cxx @@ -11,7 +11,10 @@ #define STD_TO_OUSTR( str ) OUString( str.c_str(), str.length( ), RTL_TEXTENCODING_UTF8 ) #include +#include +#include +#include #include #include @@ -64,6 +67,91 @@ namespace cmis return false; } + string AuthProvider::getRefreshToken(string& rUsername) + { + string refreshToken; + const css::uno::Reference xEnv = getXEnv(); + if (xEnv.is()) + { + uno::Reference xIH = xEnv->getInteractionHandler(); + + if (rUsername.empty()) + { + rtl::Reference xRequest + = new ucbhelper::SimpleAuthenticationRequest( + m_sUrl, m_sBindingUrl, + ucbhelper::SimpleAuthenticationRequest::EntityType::ENTITY_NA, OUString(), + ucbhelper::SimpleAuthenticationRequest::EntityType::ENTITY_MODIFY, + STD_TO_OUSTR(rUsername), + ucbhelper::SimpleAuthenticationRequest::EntityType::ENTITY_NA, OUString()); + xIH->handle(xRequest); + + rtl::Reference xSelection + = xRequest->getSelection(); + + if (xSelection.is()) + { + // Handler handled the request. + uno::Reference xAbort(xSelection.get(), + uno::UNO_QUERY); + if (!xAbort.is()) + { + const rtl::Reference& xSupp + = xRequest->getAuthenticationSupplier(); + + rUsername = OUSTR_TO_STDSTR(xSupp->getUserName()); + } + } + } + + uno::Reference xContext + = ::comphelper::getProcessComponentContext(); + uno::Reference xMasterPasswd + = task::PasswordContainer::create(xContext); + if (xMasterPasswd->hasMasterPassword()) + { + xMasterPasswd->authorizateWithMasterPassword(xIH); + } + if (xMasterPasswd->isPersistentStoringAllowed()) + { + task::UrlRecord aRec + = xMasterPasswd->findForName(m_sBindingUrl, STD_TO_OUSTR(rUsername), xIH); + if (aRec.UserList.hasElements() && aRec.UserList[0].Passwords.hasElements()) + refreshToken = OUSTR_TO_STDSTR(aRec.UserList[0].Passwords[0]); + } + } + return refreshToken; + } + + bool AuthProvider::storeRefreshToken(const string& username, const string& password, + const string& refreshToken) + { + if (refreshToken.empty()) + return false; + if (password == refreshToken) + return true; + const css::uno::Reference xEnv = getXEnv(); + if (xEnv.is()) + { + uno::Reference xIH = xEnv->getInteractionHandler(); + uno::Reference xContext + = ::comphelper::getProcessComponentContext(); + uno::Reference xMasterPasswd + = task::PasswordContainer::create(xContext); + uno::Sequence aPasswd{ STD_TO_OUSTR(refreshToken) }; + if (xMasterPasswd->isPersistentStoringAllowed()) + { + if (xMasterPasswd->hasMasterPassword()) + { + xMasterPasswd->authorizateWithMasterPassword(xIH); + } + xMasterPasswd->addPersistent(m_sBindingUrl, STD_TO_OUSTR(username), aPasswd, xIH); + return true; + } + } + return false; + } + css::uno::WeakReference< css::ucb::XCommandEnvironment> AuthProvider::sm_xEnv; void AuthProvider::setXEnv(const css::uno::Reference< css::ucb::XCommandEnvironment>& xEnv ) @@ -76,7 +164,7 @@ namespace cmis return sm_xEnv; } - char* AuthProvider::onedriveAuthCodeFallback( const char* url, + char* AuthProvider::copyWebAuthCodeFallback( const char* url, const char* /*username*/, const char* /*password*/ ) { @@ -120,46 +208,6 @@ namespace cmis return strdup( "" ); } - - char* AuthProvider::gdriveAuthCodeFallback( const char* /*url*/, - const char* /*username*/, - const char* /*password*/ ) - { - const css::uno::Reference< - css::ucb::XCommandEnvironment> xEnv = getXEnv( ); - - if ( xEnv.is() ) - { - uno::Reference< task::XInteractionHandler > xIH - = xEnv->getInteractionHandler(); - - if ( xIH.is() ) - { - rtl::Reference< ucbhelper::AuthenticationFallbackRequest > xRequest - = new ucbhelper::AuthenticationFallbackRequest ( - "PIN:", "" ); - - xIH->handle( xRequest ); - - rtl::Reference< ucbhelper::InteractionContinuation > xSelection - = xRequest->getSelection(); - - if ( xSelection.is() ) - { - // Handler handled the request. - const rtl::Reference< ucbhelper::InteractionAuthFallback >& - xAuthFallback = xRequest->getAuthFallbackInter( ); - if ( xAuthFallback.is() ) - { - OUString code = xAuthFallback->getCode( ); - return strdup( OUSTR_TO_STDSTR( code ).c_str( ) ); - } - } - } - } - - return strdup( "" ); - } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3