configure.ac | 18 desktop/source/app/updater.cxx | 4 desktop/source/minidump/minidump.cxx | 4 download.lst | 8 extensions/source/update/check/download.cxx | 4 external/curl/README | 2 external/libcmis/0001-rename-class-GetObject-to-avoid-name-clash-on-Window.patch | 69 external/libcmis/UnpackedTarball_libcmis.mk | 8 external/libcmis/libcmis-boost-string.patch | 11 external/libcmis/libcmis-libxml2_compatibility.patch | 14 external/libcmis/libcmis_gdrive.patch.1 | 702 ---------- external/libcmis/libcmis_oauth_pw_as_refreshtoken.patch.1 | 185 -- external/libcmis/libcmis_onedrive.patch | 445 ------ include/curlinit.hxx | 59 svl/source/crypto/cryptosign.cxx | 6 ucb/source/ucp/cmis/auth_provider.hxx | 8 ucb/source/ucp/cmis/cmis_content.cxx | 4 ucb/source/ucp/ftp/ftploaderthread.cxx | 4 ucb/source/ucp/webdav-curl/CurlSession.cxx | 2 19 files changed, 94 insertions(+), 1463 deletions(-)
New commits: commit 226651260fef867060e4b1d7807acea4dbedf6d8 Author: Stephan Bergmann <[email protected]> AuthorDate: Mon Jul 31 21:34:49 2023 +0200 Commit: Aron Budea <[email protected]> CommitDate: Thu Aug 8 04:48:51 2024 +0200 Update to curl-8.2.1.tar.xz ...obtained from <https://curl.se/download/curl-8.2.1.tar.xz> Change-Id: I7260f79e2f72501869ff58c77f0d9dfa3ebdece1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155116 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <[email protected]> (cherry picked from commit 85c07891ad9424661d8e1adb8e93364e3964ce34) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155133 Reviewed-by: Xisco Fauli <[email protected]> (cherry picked from commit 4b8da4693bf5322e4f18ae9168ec434c99f4f9f6) diff --git a/download.lst b/download.lst index 53d9eb8bbe6f..53404b35f696 100644 --- a/download.lst +++ b/download.lst @@ -37,8 +37,8 @@ export CPPUNIT_SHA256SUM := 89c5c6665337f56fd2db36bc3805a5619709d51fb136e5193707 export CPPUNIT_TARBALL := cppunit-1.15.1.tar.gz export CT2N_SHA256SUM := 71b238efd2734be9800af07566daea8d6685aeed28db5eb5fa0e6453f4d85de3 export CT2N_TARBALL := 1f467e5bb703f12cbbb09d5cf67ecf4a-converttexttonumber-1-5-0.oxt -export CURL_SHA256SUM := 31b1118eb8bfd43cd95d9a3f146f814ff874f6ed3999b29d94f4d1e7dbac5ef6 -export CURL_TARBALL := curl-8.1.2.tar.xz +export CURL_SHA256SUM := dd322f6bd0a20e6cebdfd388f69e98c3d183bed792cf4713c8a7ef498cba4894 +export CURL_TARBALL := curl-8.2.1.tar.xz export EBOOK_SHA256SUM := 7e8d8ff34f27831aca3bc6f9cc532c2f90d2057c778963b884ff3d1e34dfe1f9 export EBOOK_TARBALL := libe-book-0.1.3.tar.xz export EPOXY_SHA256SUM := a7ced37f4102b745ac86d6a70a9da399cc139ff168ba6b8002b4d8d43c900c15 commit d3d0c5ec145c4d593e18cf08f02d662a85d7f1bb Author: Taichi Haradaguchi <[email protected]> AuthorDate: Sat Jun 10 15:57:28 2023 +0900 Commit: Aron Budea <[email protected]> CommitDate: Thu Aug 8 04:47:25 2024 +0200 curl: upgrade to release 8.1.2 Fixes CVE-2023-28321, CVE-2023-28322, and 2 more CVEs that probably don't affect LibreOffice. Change-Id: If8720ba3647216063bffc8678aa64dad9a317128 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152809 Tested-by: Jenkins Reviewed-by: Taichi Haradaguchi <[email protected]> Reviewed-by: Michael Stahl <[email protected]> (cherry picked from commit dc19ef0d42e89edffcc21795194eb1eeb5957d0f) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152888 Reviewed-by: Xisco Fauli <[email protected]> (cherry picked from commit 244fdcf2f4a318b876acb20594811c8905125739) diff --git a/download.lst b/download.lst index fb8f0e2c4a3d..53d9eb8bbe6f 100644 --- a/download.lst +++ b/download.lst @@ -37,8 +37,8 @@ export CPPUNIT_SHA256SUM := 89c5c6665337f56fd2db36bc3805a5619709d51fb136e5193707 export CPPUNIT_TARBALL := cppunit-1.15.1.tar.gz export CT2N_SHA256SUM := 71b238efd2734be9800af07566daea8d6685aeed28db5eb5fa0e6453f4d85de3 export CT2N_TARBALL := 1f467e5bb703f12cbbb09d5cf67ecf4a-converttexttonumber-1-5-0.oxt -export CURL_SHA256SUM := 0a381cd82f4d00a9a334438b8ca239afea5bfefcfa9a1025f2bf118e79e0b5f0 -export CURL_TARBALL := curl-8.0.1.tar.xz +export CURL_SHA256SUM := 31b1118eb8bfd43cd95d9a3f146f814ff874f6ed3999b29d94f4d1e7dbac5ef6 +export CURL_TARBALL := curl-8.1.2.tar.xz export EBOOK_SHA256SUM := 7e8d8ff34f27831aca3bc6f9cc532c2f90d2057c778963b884ff3d1e34dfe1f9 export EBOOK_TARBALL := libe-book-0.1.3.tar.xz export EPOXY_SHA256SUM := a7ced37f4102b745ac86d6a70a9da399cc139ff168ba6b8002b4d8d43c900c15 diff --git a/external/curl/README b/external/curl/README index 292e4edf57b6..4a7044623608 100644 --- a/external/curl/README +++ b/external/curl/README @@ -1 +1 @@ -A URL manipulation engine from [http://curl.haxx.se/]. +A URL manipulation engine from [https://curl.se/]. commit a961590014d083501a88e41d26d8219e0550cfc0 Author: Michael Stahl <[email protected]> AuthorDate: Fri Nov 3 20:16:09 2023 +0100 Commit: Aron Budea <[email protected]> CommitDate: Thu Aug 8 04:35:11 2024 +0200 curl: mitigate migration to OpenSSL on Linux The problem is that curl 8.3.0 removed the NSS backend, so we now have no other choice than to use the bundled OpenSSL on Linux. Currently any curl https connection fails with: CurlSession.cxx:963: curl_easy_perform failed: (60) SSL certificate problem: unable to get local issuer certificate Apparently this requires manually telling curl which CA certificates to trust; there is a configure flag --with-ca-bundle but that is useless as it tries to load the file relative to whatever is the current working directory, and also did i mention that there are at least 3 different locations where a Linux system may store its system trusted CA certificates because ALL ABOUT CHOICE. So add a new header with an init function to try out various file locations listed in this nice blog article and call it from way too many places that independently use curl. https://www.happyassassin.net/posts/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/ TODO: perhaps bundle a cacert.pem as a fallback in case the system chose to innovate by putting its certificates in yet another unexpected place (regression from commit c2930ebff82c4f7ffe8377ab82627131f8544226) Change-Id: Ibf1cc0069bc2ae011ecead9a4c2b455e94b01241 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158915 Tested-by: Jenkins Reviewed-by: Michael Stahl <[email protected]> (cherry picked from commit 11f439b861922b9286b2e47ed326f3508a48d44e) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159125 Reviewed-by: Xisco Fauli <[email protected]> (cherry picked from commit 045bef390a025c3615d904524bf5ee21fa697ca4) diff --git a/desktop/source/app/updater.cxx b/desktop/source/app/updater.cxx index 2748373e5f62..c1fe24e055d8 100644 --- a/desktop/source/app/updater.cxx +++ b/desktop/source/app/updater.cxx @@ -37,6 +37,8 @@ #include <orcus/json_document_tree.hpp> #include <orcus/config.hpp> #include <orcus/pstring.hpp> + +#include <curlinit.hxx> #include <comphelper/hash.hxx> #include <com/sun/star/container/XNameAccess.hpp> @@ -546,6 +548,8 @@ std::string download_content(const OString& rURL, bool bFile, OUString& rHash) if (!curl) return std::string(); + ::InitCurl_easy(curl.get()); + curl_easy_setopt(curl.get(), CURLOPT_URL, rURL.getStr()); curl_easy_setopt(curl.get(), CURLOPT_USERAGENT, kUserAgent); bool bUseProxy = false; diff --git a/desktop/source/minidump/minidump.cxx b/desktop/source/minidump/minidump.cxx index d61922cdaac6..a3c357f78209 100644 --- a/desktop/source/minidump/minidump.cxx +++ b/desktop/source/minidump/minidump.cxx @@ -16,6 +16,8 @@ #include <curl/curl.h> +#include <curlinit.hxx> + #ifdef _WIN32 #include <memory> #include <windows.h> @@ -94,6 +96,8 @@ static bool uploadContent(std::map<std::string, std::string>& parameters, std::s if (!curl) return false; + ::InitCurl_easy(curl); + std::string proxy, proxy_user_pwd, ca_certificate_file, file, url, version; getProperty("Proxy", proxy, parameters); diff --git a/extensions/source/update/check/download.cxx b/extensions/source/update/check/download.cxx index 387c1efd7a4f..ce595c0ed4ff 100644 --- a/extensions/source/update/check/download.cxx +++ b/extensions/source/update/check/download.cxx @@ -23,6 +23,8 @@ #include <curl/curl.h> +#include <curlinit.hxx> + #include <o3tl/string_view.hxx> #include <osl/diagnose.h> #include <osl/file.h> @@ -222,6 +224,8 @@ static bool curl_run(std::u16string_view rURL, OutData& out, const OString& aPro if( nullptr != pCURL ) { + ::InitCurl_easy(pCURL); + out.curl = pCURL; OString aURL(OUStringToOString(rURL, RTL_TEXTENCODING_UTF8)); diff --git a/include/curlinit.hxx b/include/curlinit.hxx new file mode 100644 index 000000000000..8b3a9968419d --- /dev/null +++ b/include/curlinit.hxx @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <curl/curl.h> + +#if defined(LINUX) && !defined(SYSTEM_CURL) +#include <com/sun/star/uno/RuntimeException.hpp> + +#include <unistd.h> + +static char const* GetCABundleFile() +{ + // try system ones first; inspired by: + // https://www.happyassassin.net/posts/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/ + auto const candidates = { + "/etc/pki/tls/certs/ca-bundle.crt", + "/etc/pki/tls/certs/ca-bundle.trust.crt", + "/etc/ssl/certs/ca-certificates.crt", + "/var/lib/ca-certificates/ca-bundle.pem", + }; + for (char const* const candidate : candidates) + { + if (access(candidate, R_OK) == 0) + { + return candidate; + } + } + + throw css::uno::RuntimeException("no OpenSSL CA certificate bundle found"); +} + +static void InitCurl_easy(CURL* const pCURL) +{ + char const* const path = GetCABundleFile(); + auto rc = curl_easy_setopt(pCURL, CURLOPT_CAINFO, path); + if (rc != CURLE_OK) // only if OOM? + { + throw css::uno::RuntimeException("CURLOPT_CAINFO failed"); + } +} + +#else + +static void InitCurl_easy(CURL* const) +{ + // these don't use OpenSSL so CAs work out of the box +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/svl/source/crypto/cryptosign.cxx b/svl/source/crypto/cryptosign.cxx index f19c4dfcd663..6418680a1fb8 100644 --- a/svl/source/crypto/cryptosign.cxx +++ b/svl/source/crypto/cryptosign.cxx @@ -16,6 +16,10 @@ #include <svl/sigstruct.hxx> #include <config_crypto.h> +#if USE_CRYPTO_NSS +#include <curlinit.hxx> +#endif + #include <rtl/character.hxx> #include <rtl/strbuf.hxx> #include <rtl/string.hxx> @@ -1082,6 +1086,8 @@ bool Signing::Sign(OStringBuffer& rCMSHexBuffer) return false; } + ::InitCurl_easy(curl); + SAL_INFO("svl.crypto", "Setting curl to verbose: " << (curl_easy_setopt(curl, CURLOPT_VERBOSE, 1) == CURLE_OK ? "OK" : "FAIL")); if ((rc = curl_easy_setopt(curl, CURLOPT_URL, OUStringToOString(m_aSignTSA, RTL_TEXTENCODING_UTF8).getStr())) != CURLE_OK) diff --git a/ucb/source/ucp/cmis/cmis_content.cxx b/ucb/source/ucp/cmis/cmis_content.cxx index 7980a1821bba..ce28f06c4a3a 100644 --- a/ucb/source/ucp/cmis/cmis_content.cxx +++ b/ucb/source/ucp/cmis/cmis_content.cxx @@ -57,6 +57,7 @@ #include <ucbhelper/proxydecider.hxx> #include <ucbhelper/macros.hxx> #include <sax/tools/converter.hxx> +#include <curlinit.hxx> #include "auth_provider.hxx" #include "certvalidation_handler.hxx" @@ -335,6 +336,9 @@ namespace cmis new CertValidationHandler( xEnv, m_xContext, aBindingUrl.GetHost( ) ) ); libcmis::SessionFactory::setCertificateValidationHandler( certHandler ); + // init libcurl callback + libcmis::SessionFactory::setCurlInitProtocolsFunction(&::InitCurl_easy); + // Get the auth credentials AuthProvider aAuthProvider(xEnv, m_xIdentifier->getContentIdentifier(), m_aURL.getBindingUrl()); AuthProvider::setXEnv( xEnv ); diff --git a/ucb/source/ucp/ftp/ftploaderthread.cxx b/ucb/source/ucp/ftp/ftploaderthread.cxx index f5ebfe36cdda..91130fc1bc9c 100644 --- a/ucb/source/ucp/ftp/ftploaderthread.cxx +++ b/ucb/source/ucp/ftp/ftploaderthread.cxx @@ -25,6 +25,8 @@ #include "ftploaderthread.hxx" #include "curl.hxx" +#include <curlinit.hxx> + using namespace ftp; @@ -75,6 +77,8 @@ CURL* FTPLoaderThread::handle() { if(!ret) { ret = curl_easy_init(); if (ret != nullptr) { + ::InitCurl_easy(ret); + // Make sure curl is not internally using environment variables like // "ftp_proxy": if (curl_easy_setopt(ret, CURLOPT_PROXY, "") != CURLE_OK) { diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx b/ucb/source/ucp/webdav-curl/CurlSession.cxx index ca6f93744c7b..3087be35ad6d 100644 --- a/ucb/source/ucp/webdav-curl/CurlSession.cxx +++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx @@ -33,6 +33,7 @@ #include <sal/log.hxx> #include <rtl/strbuf.hxx> #include <rtl/ustrbuf.hxx> +#include <curlinit.hxx> #include <config_version.h> #include <map> @@ -680,6 +681,7 @@ CurlSession::CurlSession(uno::Reference<uno::XComponentContext> const& xContext, assert(rc == CURLE_OK); rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_HEADERFUNCTION, &header_callback); assert(rc == CURLE_OK); + ::InitCurl_easy(m_pCurl.get()); // tdf#149921 by default, with schannel (WNT) connection fails if revocation // lists cannot be checked; try to limit the checking to when revocation // lists can actually be retrieved (usually not the case for self-signed CA) commit e90310fe103d6c847b6673de98f9b3381604e9de Author: Xisco Fauli <[email protected]> AuthorDate: Tue May 14 09:53:07 2024 +0200 Commit: Aron Budea <[email protected]> CommitDate: Wed Aug 7 19:47:19 2024 +0200 libcmis: upgrade to 0.6.2 Downloaded from https://github.com/tdf/libcmis/releases/download/v0.6.2/libcmis-0.6.2.tar.xz Change-Id: I96f00da6a102bf720705060df009f57c6b93b1e4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167626 Tested-by: Jenkins Reviewed-by: Xisco Fauli <[email protected]> (cherry picked from commit bb2655206a1a2684ead8038601c70f4389a5d7aa) diff --git a/download.lst b/download.lst index 58a38462b41a..fb8f0e2c4a3d 100644 --- a/download.lst +++ b/download.lst @@ -29,8 +29,8 @@ export CLUCENE_SHA256SUM := ddfdc433dd8ad31b5c5819cc4404a8d2127472a3b720d3e744e8 export CLUCENE_TARBALL := 48d647fbd8ef8889e5a7f422c1bfda94-clucene-core-2.3.3.4.tar.gz export DTOA_SHA256SUM := 0082d0684f7db6f62361b76c4b7faba19e0c7ce5cb8e36c4b65fea8281e711b4 export DTOA_TARBALL := dtoa-20180411.tgz -export LIBCMIS_SHA256SUM := d54d19d86153dbc88e2d468f7136269a2cfe71b73227e12fded01d29ac268074 -export LIBCMIS_TARBALL := libcmis-0.6.1.tar.xz +export LIBCMIS_SHA256SUM := 1b5c2d7258ff93eb5f9958ff0e4dfd7332dc75a071bb717dde2217a26602a644 +export LIBCMIS_TARBALL := libcmis-0.6.2.tar.xz export COINMP_SHA256SUM := 86c798780b9e1f5921fe4efe651a93cb420623b45aa1fdff57af8c37f116113f export COINMP_TARBALL := CoinMP-1.7.6.tgz export CPPUNIT_SHA256SUM := 89c5c6665337f56fd2db36bc3805a5619709d51fb136e51937072f63fcc717a7 commit 26ff405ae214f35b3046f02d02ae47c04fc0f4f0 Author: Caolán McNamara <[email protected]> AuthorDate: Mon Nov 13 10:13:50 2023 +0000 Commit: Aron Budea <[email protected]> CommitDate: Wed Aug 7 19:46:30 2024 +0200 upgrade libcmis Change-Id: Ie2d5f3f8208f9952db5be10905b5905cd03b91de Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159366 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> (cherry picked from commit 3368447e826d4204086e4d8bfe59af4412c16233) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159454 Reviewed-by: Michael Stahl <[email protected]> (cherry picked from commit 25b159729f1202ca2a42de5e76f22718d68400c8) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159589 (cherry picked from commit e9320e567d6bca32783d0f716f386761d03a875a) diff --git a/configure.ac b/configure.ac index 4a5c08be221e..4a80c4cc662a 100644 --- a/configure.ac +++ b/configure.ac @@ -7326,7 +7326,7 @@ dnl Check for system libcmis dnl =================================================================== # libcmis requires curl and we can't build curl for iOS if test "$test_cmis" = "yes" -a "$enable_cmis" = "yes"; then - libo_CHECK_SYSTEM_MODULE([libcmis],[LIBCMIS],[libcmis-0.6 >= 0.6.0]) + libo_CHECK_SYSTEM_MODULE([libcmis],[LIBCMIS],[libcmis-0.6 >= 0.6.1]) ENABLE_LIBCMIS=TRUE else ENABLE_LIBCMIS= diff --git a/download.lst b/download.lst index 46b9a6e227d6..58a38462b41a 100644 --- a/download.lst +++ b/download.lst @@ -29,8 +29,8 @@ export CLUCENE_SHA256SUM := ddfdc433dd8ad31b5c5819cc4404a8d2127472a3b720d3e744e8 export CLUCENE_TARBALL := 48d647fbd8ef8889e5a7f422c1bfda94-clucene-core-2.3.3.4.tar.gz export DTOA_SHA256SUM := 0082d0684f7db6f62361b76c4b7faba19e0c7ce5cb8e36c4b65fea8281e711b4 export DTOA_TARBALL := dtoa-20180411.tgz -export LIBCMIS_SHA256SUM := 56df575f78dacc21b4cec7cec73d671fd235f7c2010a8bb7940ef1413dc899fd -export LIBCMIS_TARBALL := libcmis-0.6.0.tar.xz +export LIBCMIS_SHA256SUM := d54d19d86153dbc88e2d468f7136269a2cfe71b73227e12fded01d29ac268074 +export LIBCMIS_TARBALL := libcmis-0.6.1.tar.xz export COINMP_SHA256SUM := 86c798780b9e1f5921fe4efe651a93cb420623b45aa1fdff57af8c37f116113f export COINMP_TARBALL := CoinMP-1.7.6.tgz export CPPUNIT_SHA256SUM := 89c5c6665337f56fd2db36bc3805a5619709d51fb136e51937072f63fcc717a7 diff --git a/external/libcmis/UnpackedTarball_libcmis.mk b/external/libcmis/UnpackedTarball_libcmis.mk index 1c014d963401..5e31b8939fcb 100644 --- a/external/libcmis/UnpackedTarball_libcmis.mk +++ b/external/libcmis/UnpackedTarball_libcmis.mk @@ -13,4 +13,7 @@ $(eval $(call gb_UnpackedTarball_set_tarball,libcmis,$(LIBCMIS_TARBALL))) $(eval $(call gb_UnpackedTarball_set_patchlevel,libcmis,1)) +$(eval $(call gb_UnpackedTarball_add_patches,libcmis,\ +)) + # vim: set noet sw=4 ts=4: commit a7d25603e43be13a7df338c9956325d6bc5d99f3 Author: Caolán McNamara <[email protected]> AuthorDate: Mon Oct 9 13:46:38 2023 +0100 Commit: Aron Budea <[email protected]> CommitDate: Wed Aug 7 18:55:34 2024 +0200 upgrade to libcmis 0.6.0 Change-Id: Ia22d2efca14b1f55f45a4ecb9c487591c3117e17 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157704 Tested-by: Caolán McNamara <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> (cherry picked from commit 4e1a5d693e408db170ccf4c84b49017056f289fa) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159121 Tested-by: Jenkins Reviewed-by: Xisco Fauli <[email protected]> (cherry picked from commit 8a6dd60309002f07284ab3470674f65330368f54) diff --git a/configure.ac b/configure.ac index 587b6b1a9769..4a5c08be221e 100644 --- a/configure.ac +++ b/configure.ac @@ -7326,7 +7326,7 @@ dnl Check for system libcmis dnl =================================================================== # libcmis requires curl and we can't build curl for iOS if test "$test_cmis" = "yes" -a "$enable_cmis" = "yes"; then - libo_CHECK_SYSTEM_MODULE([libcmis],[LIBCMIS],[libcmis-0.5 >= 0.5.2]) + libo_CHECK_SYSTEM_MODULE([libcmis],[LIBCMIS],[libcmis-0.6 >= 0.6.0]) ENABLE_LIBCMIS=TRUE else ENABLE_LIBCMIS= @@ -7357,28 +7357,12 @@ elif test "$GCC" = "yes" -o "$COM_IS_CLANG" = TRUE; then fi save_CXXFLAGS=$CXXFLAGS CXXFLAGS="$CXXFLAGS $flag -Werror" - if test "$SYSTEM_LIBCMIS" = TRUE; then - CXXFLAGS="$CXXFLAGS -DSYSTEM_LIBCMIS $LIBCMIS_CFLAGS" - fi AC_LANG_PUSH([C++]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <algorithm> #include <functional> #include <vector> - #if defined SYSTEM_LIBCMIS - // See ucb/source/ucp/cmis/auth_provider.hxx: - #if !defined __clang__ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated" - #pragma GCC diagnostic ignored "-Wunused-but-set-parameter" - #endif - #include <libcmis/libcmis.hxx> - #if !defined __clang__ - #pragma GCC diagnostic pop - #endif - #endif - void f(std::vector<int> & v, std::function<bool(int, int)> fn) { std::sort(v.begin(), v.end(), fn); } diff --git a/download.lst b/download.lst index 48cc3bc01199..46b9a6e227d6 100644 --- a/download.lst +++ b/download.lst @@ -29,8 +29,8 @@ export CLUCENE_SHA256SUM := ddfdc433dd8ad31b5c5819cc4404a8d2127472a3b720d3e744e8 export CLUCENE_TARBALL := 48d647fbd8ef8889e5a7f422c1bfda94-clucene-core-2.3.3.4.tar.gz export DTOA_SHA256SUM := 0082d0684f7db6f62361b76c4b7faba19e0c7ce5cb8e36c4b65fea8281e711b4 export DTOA_TARBALL := dtoa-20180411.tgz -export LIBCMIS_SHA256SUM := d7b18d9602190e10d437f8a964a32e983afd57e2db316a07d87477a79f5000a2 -export LIBCMIS_TARBALL := libcmis-0.5.2.tar.xz +export LIBCMIS_SHA256SUM := 56df575f78dacc21b4cec7cec73d671fd235f7c2010a8bb7940ef1413dc899fd +export LIBCMIS_TARBALL := libcmis-0.6.0.tar.xz export COINMP_SHA256SUM := 86c798780b9e1f5921fe4efe651a93cb420623b45aa1fdff57af8c37f116113f export COINMP_TARBALL := CoinMP-1.7.6.tgz export CPPUNIT_SHA256SUM := 89c5c6665337f56fd2db36bc3805a5619709d51fb136e51937072f63fcc717a7 diff --git a/external/libcmis/0001-rename-class-GetObject-to-avoid-name-clash-on-Window.patch b/external/libcmis/0001-rename-class-GetObject-to-avoid-name-clash-on-Window.patch deleted file mode 100644 index f82c82f819f8..000000000000 --- a/external/libcmis/0001-rename-class-GetObject-to-avoid-name-clash-on-Window.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 219e6d6586c8280dfd9c4851cee0d14d68b6ad65 Mon Sep 17 00:00:00 2001 -From: David Tardon <[email protected]> -Date: Fri, 28 Dec 2018 15:26:28 +0100 -Subject: [PATCH] rename class GetObject to avoid name clash on Windows - ---- - src/libcmis/ws-objectservice.cxx | 2 +- - src/libcmis/ws-requests.cxx | 2 +- - src/libcmis/ws-requests.hxx | 7 +++---- - 3 files changed, 5 insertions(+), 6 deletions(-) - -diff --git a/src/libcmis/ws-objectservice.cxx b/src/libcmis/ws-objectservice.cxx -index 9e40085..d57f3cc 100644 ---- a/src/libcmis/ws-objectservice.cxx -+++ b/src/libcmis/ws-objectservice.cxx -@@ -71,7 +71,7 @@ libcmis::ObjectPtr ObjectService::getObject( string repoId, string id ) - { - libcmis::ObjectPtr object; - -- class GetObject request( repoId, id ); -+ GetObjectRequest request( repoId, id ); - vector< SoapResponsePtr > responses = m_session->soapRequest( m_url, request ); - if ( responses.size( ) == 1 ) - { -diff --git a/src/libcmis/ws-requests.cxx b/src/libcmis/ws-requests.cxx -index f8bc245..408d053 100644 ---- a/src/libcmis/ws-requests.cxx -+++ b/src/libcmis/ws-requests.cxx -@@ -269,7 +269,7 @@ SoapResponsePtr GetTypeChildrenResponse::create( xmlNodePtr node, RelatedMultipa - return SoapResponsePtr( response ); - } - --void GetObject::toXml( xmlTextWriterPtr writer ) -+void GetObjectRequest::toXml( xmlTextWriterPtr writer ) - { - xmlTextWriterStartElement( writer, BAD_CAST( "cmism:getObject" ) ); - xmlTextWriterWriteAttribute( writer, BAD_CAST( "xmlns:cmis" ), BAD_CAST( NS_CMIS_URL ) ); -diff --git a/src/libcmis/ws-requests.hxx b/src/libcmis/ws-requests.hxx -index 2c4ae92..534d9a4 100644 ---- a/src/libcmis/ws-requests.hxx -+++ b/src/libcmis/ws-requests.hxx -@@ -203,21 +203,20 @@ class GetTypeChildrenResponse : public SoapResponse - std::vector< libcmis::ObjectTypePtr > getChildren( ) { return m_children; } - }; - --#undef GetObject --class GetObject : public SoapRequest -+class GetObjectRequest : public SoapRequest - { - private: - std::string m_repositoryId; - std::string m_id; - - public: -- GetObject( std::string repoId, std::string id ) : -+ GetObjectRequest( std::string repoId, std::string id ) : - m_repositoryId( repoId ), - m_id( id ) - { - } - -- ~GetObject( ) { } -+ ~GetObjectRequest( ) { } - - void toXml( xmlTextWriterPtr writer ); - }; --- -2.19.2 - diff --git a/external/libcmis/UnpackedTarball_libcmis.mk b/external/libcmis/UnpackedTarball_libcmis.mk index f48201d319d0..1c014d963401 100644 --- a/external/libcmis/UnpackedTarball_libcmis.mk +++ b/external/libcmis/UnpackedTarball_libcmis.mk @@ -13,13 +13,4 @@ $(eval $(call gb_UnpackedTarball_set_tarball,libcmis,$(LIBCMIS_TARBALL))) $(eval $(call gb_UnpackedTarball_set_patchlevel,libcmis,1)) -$(eval $(call gb_UnpackedTarball_add_patches,libcmis, \ - external/libcmis/libcmis-libxml2_compatibility.patch \ - external/libcmis/0001-rename-class-GetObject-to-avoid-name-clash-on-Window.patch \ - external/libcmis/libcmis_onedrive.patch \ - external/libcmis/libcmis_oauth_pw_as_refreshtoken.patch.1 \ - external/libcmis/libcmis_gdrive.patch.1 \ - external/libcmis/libcmis-boost-string.patch \ -)) - # vim: set noet sw=4 ts=4: diff --git a/external/libcmis/libcmis-boost-string.patch b/external/libcmis/libcmis-boost-string.patch deleted file mode 100644 index 247d38a19759..000000000000 --- a/external/libcmis/libcmis-boost-string.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/src/libcmis/oauth2-handler.cxx -+++ b/src/libcmis/oauth2-handler.cxx -@@ -26,6 +26,8 @@ - * instead of those above. - */ - -+#include <boost/algorithm/string.hpp> -+ - #include "oauth2-handler.hxx" - - #include <libcmis/session-factory.hxx> diff --git a/external/libcmis/libcmis-libxml2_compatibility.patch b/external/libcmis/libcmis-libxml2_compatibility.patch deleted file mode 100644 index 240b85b4d38e..000000000000 --- a/external/libcmis/libcmis-libxml2_compatibility.patch +++ /dev/null @@ -1,14 +0,0 @@ -# -*- Mode: Diff -*- ---- a/src/libcmis/oauth2-providers.cxx -+++ b/src/libcmis/oauth2-providers.cxx -@@ -34,6 +34,10 @@ - - using namespace std; - -+#if LIBXML_VERSION < 20621 -+#define HTML_PARSE_RECOVER 0 -+#endif -+ - namespace { - - // Encodes the given data according to the application/x-www-form-urlencoded format, see diff --git a/external/libcmis/libcmis_gdrive.patch.1 b/external/libcmis/libcmis_gdrive.patch.1 deleted file mode 100644 index 24ff65d1ef15..000000000000 --- a/external/libcmis/libcmis_gdrive.patch.1 +++ /dev/null @@ -1,702 +0,0 @@ -diff -ur libcmis.org/src/libcmis/gdrive-document.cxx libcmis/src/libcmis/gdrive-document.cxx ---- libcmis.org/src/libcmis/gdrive-document.cxx 2021-07-27 19:11:02.679247008 +0200 -+++ libcmis/src/libcmis/gdrive-document.cxx 2021-07-27 19:11:18.873246420 +0200 -@@ -145,23 +145,17 @@ - { - if ( !os.get( ) ) - throw libcmis::Exception( "Missing stream" ); -- if ( !isImmutable( ) ) -- throw libcmis::Exception( string ( "Document " + getId( )+ -- " is not editable" ) ); -- string putUrl = getUploadUrl( ) + getId( ); -- putUrl += "?uploadType=media"; -- -- // If it's a Google document, convert it -- if ( isGoogleDoc( ) ) -- putUrl += "&convert=true"; -+ -+ string putUrl = GDRIVE_UPLOAD_LINK + getId( ) + "?uploadType=media"; - - // Upload stream - boost::shared_ptr< istream> is ( new istream ( os->rdbuf( ) ) ); - vector <string> headers; - headers.push_back( string( "Content-Type: " ) + contentType ); -+ string res; - try - { -- getSession()->httpPutRequest( putUrl, *is, headers ); -+ res = getSession()->httpPatchRequest( putUrl, *is, headers )->getStream()->str(); - } - catch ( const CurlException& e ) - { -@@ -181,35 +175,10 @@ - { - if ( !os.get( ) ) - throw libcmis::Exception( "Missing stream" ); -- -- if ( !isImmutable( ) ) -- throw libcmis::Exception( string ( "Document " + getId( )+ -- " is not editable" ) ); -- string metaUrl = getUrl( ); -- -- // If it's a Google document, convert it -- if ( isGoogleDoc( ) ) -- metaUrl += "?convert=true"; -- -- // Update file name meta information -- if ( !fileName.empty( ) && fileName != getContentFilename( ) ) -- { -- Json metaJson; -- Json fileJson( fileName.c_str( ) ); -- metaJson.add("title", fileJson ); -- -- std::istringstream is( metaJson.toString( ) ); -- vector<string> headers; -- headers.push_back( "Content-Type: application/json" ); -- try -- { -- getSession()->httpPutRequest( metaUrl, is, headers ); -- } -- catch ( const CurlException& e ) -- { -- throw e.getCmisException( ); -- } -- } -+ -+ // TODO: when would the filename need an update? -+ if (!fileName.empty() && fileName != getContentFilename()) -+ std::cout << "filename change is not implemented in setContentStream" << std::endl; - - // Upload stream - uploadStream( os, contentType ); -@@ -251,7 +220,7 @@ - vector< libcmis::DocumentPtr > GDriveDocument::getAllVersions( ) - { - vector< libcmis::DocumentPtr > revisions; -- string versionUrl = getUrl( ) + "/revisions"; -+ string versionUrl = GDRIVE_METADATA_LINK + getId( ) + "/revisions"; - // Run the http request to get the properties definition - string res; - try -@@ -263,7 +232,7 @@ - throw e.getCmisException( ); - } - Json jsonRes = Json::parse( res ); -- Json::JsonVector objs = jsonRes["items"].getList( ); -+ Json::JsonVector objs = jsonRes["revisions"].getList( ); - - string parentId = getStringProperty( "cmis:parentId" ); - -diff -ur libcmis.org/src/libcmis/gdrive-folder.cxx libcmis/src/libcmis/gdrive-folder.cxx ---- libcmis.org/src/libcmis/gdrive-folder.cxx 2021-07-27 19:11:02.678247008 +0200 -+++ libcmis/src/libcmis/gdrive-folder.cxx 2021-07-27 19:11:18.874246420 +0200 -@@ -62,8 +62,8 @@ - // Instead of sending multiple queries for children, - // we send a single query to search for objects where parents - // include the folderID. -- string query = getSession( )->getBindingUrl( ) + -- "/files?q=\"" + getId( ) + "\"+in+parents+and+trashed+=+false"; -+ string query = GDRIVE_METADATA_LINK + "?q=\"" + getId( ) + "\"+in+parents+and+trashed+=+false" + -+ "&fields=files(kind,id,name,parents,mimeType,createdTime,modifiedTime,thumbnailLink,size)"; - - string res; - try -@@ -76,7 +76,7 @@ - } - - Json jsonRes = Json::parse( res ); -- Json::JsonVector objs = jsonRes["items"].getList( ); -+ Json::JsonVector objs = jsonRes["files"].getList( ); - - // Create children objects from Json objects - for(unsigned int i = 0; i < objs.size(); i++) -@@ -95,7 +95,7 @@ - string GDriveFolder::uploadProperties( Json properties ) - { - // URL for uploading meta data -- string metaUrl = getSession()->getBindingUrl() + "/files/"; -+ string metaUrl = GDRIVE_METADATA_LINK + "?fields=kind,id,name,parents,mimeType,createdTime,modifiedTime"; - - // add parents to the properties - properties.add( "parents", GdriveUtils::createJsonFromParentId( getId( ) ) ); -@@ -147,9 +147,15 @@ - - Json propsJson = GdriveUtils::toGdriveJson( properties ); - -- // Add filename to properties -- Json jsonFilename( fileName.c_str( ) ); -- propsJson.add( "title", jsonFilename ); -+ if(!fileName.empty()) { -+ // use provided filename -+ Json jsonFilename( fileName.c_str( ) ); -+ -+ propsJson.add( "name", jsonFilename ); -+ } -+ if(!contentType.empty()) { -+ propsJson.add( "mimeType", Json(contentType.c_str())); -+ } - - // Upload meta-datas - string res = uploadProperties( propsJson); -@@ -171,12 +177,9 @@ - libcmis::UnfileObjects::Type /*unfile*/, - bool /*continueOnError*/ ) - { -- // Object remove doesn't work with folder -- // Using trash instead - try - { -- istringstream is( "" ); -- getSession( )->httpPostRequest( getUrl( ) + "/trash", is, "" ); -+ getSession( )->httpDeleteRequest( GDRIVE_METADATA_LINK + getId( ) ); - } - catch ( const CurlException& e ) - { -diff -ur libcmis.org/src/libcmis/gdrive-object.cxx libcmis/src/libcmis/gdrive-object.cxx ---- libcmis.org/src/libcmis/gdrive-object.cxx 2021-07-27 19:11:02.675247009 +0200 -+++ libcmis/src/libcmis/gdrive-object.cxx 2021-07-27 19:11:18.874246420 +0200 -@@ -89,8 +89,8 @@ - property.reset( new GDriveProperty( it->first, it->second ) ); - m_properties[ property->getPropertyType( )->getId()] = property; - -- // we map "title" to both "cmis:name" and "cmis:getContentStreamFileName" -- if ( it->first == "title" ) -+ // we map "name" to both "cmis:name" and "cmis:getContentStreamFileName" -+ if ( it->first == "name" ) - { - property.reset( new GDriveProperty( "cmis:name", it->second) ); - m_properties[ property->getPropertyType( )->getId()] = property; -@@ -142,16 +142,13 @@ - { - if ( m_renditions.empty( ) ) - { -- string downloadUrl = getStringProperty( "downloadUrl" ); -- if ( !downloadUrl.empty( ) ) -- { -- string mimeType = getStringProperty( "cmis:contentStreamMimeType" ); -- if ( !mimeType.empty( ) ) -- { -- RenditionPtr rendition( -- new Rendition( mimeType, mimeType, mimeType, downloadUrl )); -- m_renditions.push_back( rendition ); -- } -+ string downloadUrl = GDRIVE_METADATA_LINK + getId( ) + "?alt=media"; -+ string mimeType = getStringProperty( "cmis:contentStreamMimeType" ); -+ if ( !mimeType.empty( ) ) -+ { -+ RenditionPtr rendition( -+ new Rendition( mimeType, mimeType, mimeType, downloadUrl )); -+ m_renditions.push_back( rendition ); - } - - vector< string > exportLinks = getMultiStringProperty( "exportLinks" ); -@@ -192,7 +189,7 @@ - { - vector< string > headers; - headers.push_back( "Content-Type: application/json" ); -- response = getSession( )->httpPutRequest( getUrl( ), is, headers ); -+ response = getSession( )->httpPatchRequest( getUrl( ), is, headers ); - } - catch ( const CurlException& e ) - { -@@ -228,7 +225,7 @@ - { - try - { -- getSession( )->httpDeleteRequest( getUrl( ) ); -+ getSession( )->httpDeleteRequest( GDRIVE_METADATA_LINK + getId( ) ); - } - catch ( const CurlException& e ) - { -@@ -239,8 +236,8 @@ - void GDriveObject::move( FolderPtr /*source*/, FolderPtr destination ) - { - Json parentsJson; -- Json parentsValue = GdriveUtils::createJsonFromParentId( destination->getId( ) ); -- parentsJson.add( "parents", parentsValue ); -+ parentsJson.add( "addParents", Json(destination->getId( ).c_str()) ); -+ parentsJson.add( "removeParents", Json(getStringProperty( "cmis:parentId" ).c_str()) ); - - istringstream is( parentsJson.toString( ) ); - libcmis::HttpResponsePtr response; -@@ -248,7 +245,7 @@ - { - vector< string > headers; - headers.push_back( "Content-Type: application/json" ); -- response = getSession( )->httpPutRequest( getUrl( ), is, headers ); -+ response = getSession( )->httpPatchRequest( getUrl( ), is, headers ); - } - catch ( const CurlException& e ) - { -@@ -262,12 +259,10 @@ - - string GDriveObject::getUrl( ) - { -- return getSession( )->getBindingUrl( ) + "/files/" + getId( ); --} -- --string GDriveObject::getUploadUrl( ) --{ -- return GDRIVE_UPLOAD_LINKS; -+ // thumbnailLink causes some operations to fail with internal server error, -+ // see https://issuetracker.google.com/issues/36760667 -+ return GDRIVE_METADATA_LINK + getId( ) + -+ "?fields=kind,id,name,parents,mimeType,createdTime,modifiedTime,size"; - } - - vector< string> GDriveObject::getMultiStringProperty( const string& propertyName ) -diff -ur libcmis.org/src/libcmis/gdrive-repository.cxx libcmis/src/libcmis/gdrive-repository.cxx ---- libcmis.org/src/libcmis/gdrive-repository.cxx 2021-07-27 19:11:02.676247009 +0200 -+++ libcmis/src/libcmis/gdrive-repository.cxx 2021-07-27 19:11:18.874246420 +0200 -@@ -35,7 +35,7 @@ - m_name = "Google Drive"; - m_description = "Google Drive repository"; - m_productName = "Google Drive"; -- m_productVersion = "v2"; -+ m_productVersion = "v3"; - m_rootId = "root"; - - m_capabilities[ ACL ] = "discover"; -diff -ur libcmis.org/src/libcmis/gdrive-session.cxx libcmis/src/libcmis/gdrive-session.cxx ---- libcmis.org/src/libcmis/gdrive-session.cxx 2021-07-27 19:11:02.675247009 +0200 -+++ libcmis/src/libcmis/gdrive-session.cxx 2021-07-27 19:11:18.874246420 +0200 -@@ -124,9 +124,13 @@ - - libcmis::ObjectPtr GDriveSession::getObject( string objectId ) - { -+ if(objectId == "root") { -+ return getRootFolder(); -+ } - // Run the http request to get the properties definition - string res; -- string objectLink = m_bindingUrl + "/files/" + objectId; -+ string objectLink = GDRIVE_METADATA_LINK + objectId + -+ "?fields=kind,id,name,parents,mimeType,createdTime,modifiedTime,thumbnailLink,size"; - try - { - res = httpGetRequest( objectLink )->getStream()->str(); -@@ -188,9 +192,10 @@ - { - // Normal child case - // Ask for the ID of the child if there is any -- string childIdUrl = m_bindingUrl + "/files/" + objectId + -- "/children/?q=title+=+'" + segment + -- "'&fields=items:id"; -+ // somewhat flawed as names are not necessarily unique in GDrive... -+ string query = libcmis::escape("'" + objectId + "' in parents and trashed = false and name='" + segment + "'"); -+ -+ string childIdUrl = m_bindingUrl + "/files/?q=" + query + "&fields=files(id)"; - - string res; - try -@@ -204,7 +209,7 @@ - Json jsonRes = Json::parse( res ); - - // Did we get an id? -- Json::JsonVector items = jsonRes["items"].getList(); -+ Json::JsonVector items = jsonRes["files"].getList(); - if ( items.empty( ) ) - throw libcmis::Exception( "Object not found: " + path, "objectNotFound" ); - -@@ -219,6 +224,27 @@ - return getObject( objectId ); - } - -+libcmis::FolderPtr GDriveSession::getRootFolder() -+{ -+ // permissions/scope with just drive.file don't allow to get it with the "root" alias/by its actual object-ID -+ Json propsJson; -+ -+ // GDrive folder is a file with a different mime type. -+ string mimeType = GDRIVE_FOLDER_MIME_TYPE; -+ -+ // Add mimetype to the propsJson -+ Json jsonMimeType( mimeType.c_str( ) ); -+ propsJson.add( "mimeType", jsonMimeType ); -+ propsJson.add( "id", "root" ); -+ -+ // Upload meta-datas -+ propsJson.add("cmis:name", "VirtualRoot"); -+ -+ libcmis::FolderPtr folderPtr( new GDriveFolder( this, propsJson ) ); -+ -+ return folderPtr; -+} -+ - libcmis::ObjectTypePtr GDriveSession::getType( string id ) - { - libcmis::ObjectTypePtr type( new GdriveObjectType( id ) ); -diff -ur libcmis.org/src/libcmis/gdrive-session.hxx libcmis/src/libcmis/gdrive-session.hxx ---- libcmis.org/src/libcmis/gdrive-session.hxx 2021-07-27 19:11:02.675247009 +0200 -+++ libcmis/src/libcmis/gdrive-session.hxx 2021-07-27 19:11:18.875246420 +0200 -@@ -57,6 +57,8 @@ - - virtual std::vector< libcmis::ObjectTypePtr > getBaseTypes( ); - -+ virtual libcmis::FolderPtr getRootFolder(); -+ - virtual std::string getRefreshToken(); - - private: -diff -ur libcmis.org/src/libcmis/gdrive-utils.cxx libcmis/src/libcmis/gdrive-utils.cxx ---- libcmis.org/src/libcmis/gdrive-utils.cxx 2021-07-27 19:11:02.677247008 +0200 -+++ libcmis/src/libcmis/gdrive-utils.cxx 2021-07-27 19:11:18.875246420 +0200 -@@ -44,17 +44,17 @@ - convertedKey = "cmis:createdBy"; - else if ( key == "description" ) - convertedKey = "cmis:description"; -- else if ( key == "createdDate" ) -+ else if ( key == "createdTime" ) - convertedKey = "cmis:creationDate"; - else if ( key == "lastModifyingUserName" ) - convertedKey = "cmis:lastModifiedBy"; -- else if ( key == "modifiedDate" ) -+ else if ( key == "modifiedTime" ) - convertedKey = "cmis:lastModificationDate"; -- else if ( key == "title" ) -+ else if ( key == "name" ) - convertedKey = "cmis:contentStreamFileName"; - else if ( key == "mimeType" ) - convertedKey = "cmis:contentStreamMimeType"; -- else if ( key == "fileSize" ) -+ else if ( key == "size" ) - convertedKey = "cmis:contentStreamLength"; - else if ( key == "editable" ) - convertedKey = "cmis:isImmutable"; -@@ -72,21 +72,21 @@ - else if ( key == "cmis:createdBy" ) - convertedKey = "ownerNames"; - else if ( key == "cmis:creationDate" ) -- convertedKey = "createdDate"; -+ convertedKey = "createdTime"; - else if ( key == "cmis:description" ) - convertedKey = "description"; - else if ( key == "cmis:lastModifiedBy" ) - convertedKey = "lastModifyingUserName"; - else if ( key == "cmis:lastModificationDate" ) -- convertedKey = "modifiedDate"; -+ convertedKey = "modifiedTime"; - else if ( key == "cmis:contentStreamFileName" ) -- convertedKey = "title"; -+ convertedKey = "name"; - else if ( key == "cmis:name" ) -- convertedKey = "title"; -+ convertedKey = "name"; - else if ( key == "cmis:contentStreamMimeType" ) - convertedKey = "mimeType"; - else if ( key == "cmis:contentStreamLength" ) -- convertedKey = "fileSize"; -+ convertedKey = "size"; - else if ( key == "cmis:isImmutable" ) - convertedKey = "editable"; - else if ( key == "cmis:parentId" ) -@@ -124,9 +124,9 @@ - bool GdriveUtils::checkUpdatable( const string& key ) - { - // taken from https://developers.google.com/drive/v2/reference/files -- bool updatable = ( key == "title" || -+ bool updatable = ( key == "name" || - key == "description" || -- key == "modifiedDate" || -+ key == "modifiedTime" || - key == "lastViewedByMeDate" ); - return updatable; - } -@@ -143,18 +143,11 @@ - - Json GdriveUtils::createJsonFromParentId( const string& parentId ) - { -- Json parentValue( parentId.c_str( ) ); -- - // parents is a Json array - Json firstParent; -- firstParent.add( "id", parentValue ); -- -- Json::JsonVector parents; -- parents.insert( parents.begin( ), firstParent ); -+ firstParent.add( Json( parentId.c_str() ) ); - -- Json parentsValue( parents ); -- -- return parentsValue; -+ return firstParent; - } - - vector< string > GdriveUtils::parseGdriveProperty( string key, Json json ) -diff -ur libcmis.org/src/libcmis/gdrive-utils.hxx libcmis/src/libcmis/gdrive-utils.hxx ---- libcmis.org/src/libcmis/gdrive-utils.hxx 2021-07-27 19:11:02.677247008 +0200 -+++ libcmis/src/libcmis/gdrive-utils.hxx 2021-07-27 19:11:18.875246420 +0200 -@@ -35,7 +35,8 @@ - #include "json-utils.hxx" - - static const std::string GDRIVE_FOLDER_MIME_TYPE = "application/vnd.google-apps.folder" ; --static const std::string GDRIVE_UPLOAD_LINKS = "https://www.googleapis.com/upload/drive/v2/files/"; -+static const std::string GDRIVE_UPLOAD_LINK = "https://www.googleapis.com/upload/drive/v3/files/"; -+static const std::string GDRIVE_METADATA_LINK = "https://www.googleapis.com/drive/v3/files/"; - - class GdriveUtils - { -diff -ur libcmis.org/src/libcmis/oauth2-handler.cxx libcmis/src/libcmis/oauth2-handler.cxx ---- libcmis.org/src/libcmis/oauth2-handler.cxx 2021-07-27 19:11:02.676247009 +0200 -+++ libcmis/src/libcmis/oauth2-handler.cxx 2021-07-27 19:11:18.875246420 +0200 -@@ -92,8 +92,11 @@ - "code=" + authCode + - "&client_id=" + m_data->getClientId() + - "&redirect_uri=" + m_data->getRedirectUri() + -- "&scope=" + libcmis::escape( m_data->getScope() ) + - "&grant_type=authorization_code" ; -+ if(boost::starts_with(m_data->getTokenUrl(), "https://oauth2.googleapis.com/")) -+ post += "&client_secret=" + m_data->getClientSecret(); -+ else -+ post += "&scope=" + libcmis::escape( m_data->getScope() ); - - istringstream is( post ); - -@@ -104,7 +107,7 @@ - resp = m_session->httpPostRequest ( m_data->getTokenUrl(), is, - "application/x-www-form-urlencoded" ); - } -- catch ( const CurlException& ) -+ catch ( const CurlException& e) - { - throw libcmis::Exception( - "Couldn't get tokens from the authorization code "); -@@ -122,6 +125,8 @@ - "refresh_token=" + m_refresh + - "&client_id=" + m_data->getClientId() + - "&grant_type=refresh_token" ; -+ if(boost::starts_with(m_data->getTokenUrl(), "https://oauth2.googleapis.com/")) -+ post += "&client_secret=" + m_data->getClientSecret(); - - istringstream is( post ); - libcmis::HttpResponsePtr resp; -@@ -130,7 +135,7 @@ - resp = m_session->httpPostRequest( m_data->getTokenUrl( ), is, - "application/x-www-form-urlencoded" ); - } -- catch (const CurlException& ) -+ catch (const CurlException& e ) - { - throw libcmis::Exception( "Couldn't refresh token "); - } -diff -ur libcmis.org/src/libcmis/oauth2-providers.cxx libcmis/src/libcmis/oauth2-providers.cxx ---- libcmis.org/src/libcmis/oauth2-providers.cxx 2021-07-27 19:11:02.679247008 +0200 -+++ libcmis/src/libcmis/oauth2-providers.cxx 2021-07-27 19:11:18.886246420 +0200 -@@ -80,172 +80,8 @@ - - } - --string OAuth2Providers::OAuth2Gdrive( HttpSession* session, const string& authUrl, -- const string& username, const string& password ) --{ -- /* This member function implements 'Google OAuth 2.0' -- * -- * The interaction is carried out by libcmis, with no web browser involved. -- * -- * Normal sequence (without 2FA) is: -- * 1) a get to activate login page -- * receive first login page, html format -- * 2) subsequent post to sent email -- * receive html page for password input -- * 3) subsequent post to send password -- * receive html page for application consent -- * 4) subsequent post to send a consent for the application -- * receive a single-use authorization code -- * this code is returned as a string -- * -- * Sequence with 2FA is: -- * 1) a get to activate login page -- * receive first login page, html format -- * 2) subsequent post to sent email -- * receive html page for password input -- * 3) subsequent post to send password -- * receive html page for pin input -- * 3b) subsequent post to send pin number -- * receive html page for application consent -- * 4) subsequent post to send a consent for the application -- * receive a single-use authorization code -- * this code is returned as a string -- */ -- -- static const string CONTENT_TYPE( "application/x-www-form-urlencoded" ); -- // STEP 1: get login page -- string res; -- try -- { -- // send the first get, receive the html login page -- res = session->httpGetRequest( authUrl )->getStream( )->str( ); -- } -- catch ( const CurlException& ) -- { -- return string( ); -- } -- -- // STEP 2: send email -- -- string loginEmailPost, loginEmailLink; -- if ( !parseResponse( res.c_str( ), loginEmailPost, loginEmailLink ) ) -- return string( ); -- -- loginEmailPost += "Email="; -- loginEmailPost += escapeForm( username ); -- -- istringstream loginEmailIs( loginEmailPost ); -- string loginEmailRes; -- try -- { -- // send a post with user email, receive the html page for password input -- loginEmailRes = session->httpPostRequest ( loginEmailLink, loginEmailIs, CONTENT_TYPE ) -- ->getStream( )->str( ); -- } -- catch ( const CurlException& ) -- { -- return string( ); -- } -- -- // STEP 3: password page -- -- string loginPasswdPost, loginPasswdLink; -- if ( !parseResponse( loginEmailRes.c_str( ), loginPasswdPost, loginPasswdLink ) ) -- return string( ); -- -- loginPasswdPost += "Passwd="; -- loginPasswdPost += escapeForm( password ); -- -- istringstream loginPasswdIs( loginPasswdPost ); -- string loginPasswdRes; -- try -- { -- // send a post with user password, receive the application consent page -- loginPasswdRes = session->httpPostRequest ( loginPasswdLink, loginPasswdIs, CONTENT_TYPE ) -- ->getStream( )->str( ); -- } -- catch ( const CurlException& ) -- { -- return string( ); -- } -- -- string approvalPost, approvalLink; -- if ( !parseResponse( loginPasswdRes. c_str( ), approvalPost, approvalLink) ) -- return string( ); -- -- // when 2FA is enabled, link doesn't start with 'http' -- if ( approvalLink.compare(0, 4, "http") != 0 ) -- { -- // STEP 3b: 2 Factor Authentication, pin code request -- -- string loginChallengePost( approvalPost ); -- string loginChallengeLink( approvalLink ); -- -- libcmis::OAuth2AuthCodeProvider fallbackProvider = libcmis::SessionFactory::getOAuth2AuthCodeProvider( ); -- unique_ptr< char, void (*)( void * ) > pin{ fallbackProvider( "", "", "" ), free }; -- -- if( !pin ) -- { -- // unset OAuth2AuthCode Provider to avoid showing pin request again in the HttpSession::oauth2Authenticate -- libcmis::SessionFactory::setOAuth2AuthCodeProvider( NULL ); -- return string( ); -- } -- -- loginChallengeLink = "https://accounts.google.com" + loginChallengeLink; -- loginChallengePost += string( PIN_INPUT_NAME ) + "="; -- loginChallengePost += string( pin.get() ); -- -- istringstream loginChallengeIs( loginChallengePost ); -- string loginChallengeRes; -- try -- { -- // send a post with pin, receive the application consent page -- loginChallengeRes = session->httpPostRequest ( loginChallengeLink, loginChallengeIs, CONTENT_TYPE ) -- ->getStream( )->str( ); -- } -- catch ( const CurlException& ) -- { -- return string( ); -- } -- -- approvalPost = string(); -- approvalLink = string(); -- -- if ( !parseResponse( loginChallengeRes. c_str( ), approvalPost, approvalLink) ) -- return string( ); -- } -- else if( approvalLink.compare( "https://accounts.google.com/ServiceLoginAuth" ) == 0 ) -- { -- // wrong password, -- // unset OAuth2AuthCode Provider to avoid showing pin request again in the HttpSession::oauth2Authenticate -- libcmis::SessionFactory::setOAuth2AuthCodeProvider( NULL ); -- return string( ); -- } -- -- // STEP 4: allow libcmis to access google drive -- approvalPost += "submit_access=true"; -- -- istringstream approvalIs( approvalPost ); -- string approvalRes; -- try -- { -- // send a post with application consent -- approvalRes = session->httpPostRequest ( approvalLink, approvalIs, -- CONTENT_TYPE) ->getStream( )->str( ); -- } -- catch ( const CurlException& e ) -- { -- throw e.getCmisException( ); -- } -- -- // Take the authentication code from the text bar -- string code = parseCode( approvalRes.c_str( ) ); -- -- return code; --} -- --string OAuth2Providers::OAuth2Onedrive( HttpSession* /*session*/, const string& /*authUrl*/, -- const string& /*username*/, const string& /*password*/ ) -+string OAuth2Providers::OAuth2Dummy( HttpSession* /*session*/, const string& /*authUrl*/, -+ const string& /*username*/, const string& /*password*/ ) - { - return string( ); - } -@@ -314,12 +150,8 @@ - // For Alfresco in the cloud, only match the hostname as there can be several - // binding URLs created with it. - return OAuth2Alfresco; -- else if ( boost::starts_with( url, "https://www.googleapis.com/drive/v2" ) ) -- return OAuth2Gdrive; -- else if ( boost::starts_with( url, "https://graph.microsoft.com/v1.0" ) ) -- return OAuth2Onedrive; - -- return OAuth2Gdrive; -+ return OAuth2Dummy; - } - - int OAuth2Providers::parseResponse ( const char* response, string& post, string& link ) -diff -ur libcmis.org/src/libcmis/oauth2-providers.hxx libcmis/src/libcmis/oauth2-providers.hxx ---- libcmis.org/src/libcmis/oauth2-providers.hxx 2021-07-27 19:11:02.678247008 +0200 -+++ libcmis/src/libcmis/oauth2-providers.hxx 2021-07-27 19:11:18.886246420 +0200 -@@ -39,12 +39,8 @@ - class OAuth2Providers - { - public : -- static std::string OAuth2Gdrive( HttpSession* session, const std::string& authUrl, -+ static std::string OAuth2Dummy( HttpSession* session, const std::string& authUrl, - const std::string& username, const std::string& password ); -- -- static std::string OAuth2Onedrive( HttpSession* session, const std::string& authUrl, -- const std::string& username, const std::string& password ); -- - static std::string OAuth2Alfresco( HttpSession* session, const std::string& authUrl, - const std::string& username, const std::string& password ); - -diff -ur libcmis.org/src/libcmis/session-factory.cxx libcmis/src/libcmis/session-factory.cxx ---- libcmis.org/src/libcmis/session-factory.cxx 2021-07-27 19:11:02.679247008 +0200 -+++ libcmis/src/libcmis/session-factory.cxx 2021-07-27 19:11:18.886246420 +0200 -@@ -66,7 +66,7 @@ - if ( !bindingUrl.empty( ) ) - { - // Try the special cases based on the binding URL -- if ( bindingUrl == "https://www.googleapis.com/drive/v2" ) -+ if ( bindingUrl == "https://www.googleapis.com/drive/v3" ) - { - session = new GDriveSession( bindingUrl, username, password, - oauth2, verbose ); diff --git a/external/libcmis/libcmis_oauth_pw_as_refreshtoken.patch.1 b/external/libcmis/libcmis_oauth_pw_as_refreshtoken.patch.1 deleted file mode 100644 index a8cb06509421..000000000000 --- a/external/libcmis/libcmis_oauth_pw_as_refreshtoken.patch.1 +++ /dev/null @@ -1,185 +0,0 @@ -diff -ur libcmis.org/inc/libcmis/session.hxx libcmis/inc/libcmis/session.hxx ---- libcmis.org/inc/libcmis/session.hxx 2021-07-27 19:09:42.580249917 +0200 -+++ libcmis/inc/libcmis/session.hxx 2021-07-27 19:10:02.368249199 +0200 -@@ -95,6 +95,8 @@ - certificate exception feature available on common web browser. - */ - virtual void setNoSSLCertificateCheck( bool noCheck ) = 0; -+ -+ virtual std::string getRefreshToken() { return ""; }; - }; - } - -diff -ur libcmis.org/src/libcmis/gdrive-session.cxx libcmis/src/libcmis/gdrive-session.cxx ---- libcmis.org/src/libcmis/gdrive-session.cxx 2021-07-27 19:09:42.581249917 +0200 -+++ libcmis/src/libcmis/gdrive-session.cxx 2021-07-27 19:10:02.369249198 +0200 -@@ -70,6 +70,46 @@ - { - } - -+ -+void GDriveSession::setOAuth2Data( libcmis::OAuth2DataPtr oauth2 ) -+{ -+ m_oauth2Handler = new OAuth2Handler( this, oauth2 ); -+ m_oauth2Handler->setOAuth2Parser( OAuth2Providers::getOAuth2Parser( getBindingUrl( ) ) ); -+ -+ oauth2Authenticate( ); -+} -+ -+void GDriveSession::oauth2Authenticate() -+{ -+ // treat the supplied password as refresh token -+ if (!m_password.empty()) -+ { -+ try -+ { -+ m_inOAuth2Authentication = true; -+ -+ m_oauth2Handler->setRefreshToken(m_password); -+ // Try to get new access tokens using the stored refreshtoken -+ m_oauth2Handler->refresh(); -+ m_inOAuth2Authentication = false; -+ } -+ catch (const CurlException &e) -+ { -+ m_inOAuth2Authentication = false; -+ // refresh token expired or invalid, trigger initial auth (that in turn will hit the fallback with copy'n'paste method) -+ BaseSession::oauth2Authenticate(); -+ } -+ } -+ else -+ { -+ BaseSession::oauth2Authenticate(); -+ } -+} -+ -+string GDriveSession::getRefreshToken() { -+ return HttpSession::getRefreshToken(); -+} -+ - libcmis::RepositoryPtr GDriveSession::getRepository( ) - { - // Return a dummy repository since GDrive doesn't have that notion -diff -ur libcmis.org/src/libcmis/gdrive-session.hxx libcmis/src/libcmis/gdrive-session.hxx ---- libcmis.org/src/libcmis/gdrive-session.hxx 2021-07-27 19:09:42.583249917 +0200 -+++ libcmis/src/libcmis/gdrive-session.hxx 2021-07-27 19:10:02.369249198 +0200 -@@ -57,8 +57,14 @@ - - virtual std::vector< libcmis::ObjectTypePtr > getBaseTypes( ); - -+ virtual std::string getRefreshToken(); -+ - private: - GDriveSession( ); -+ -+ virtual void setOAuth2Data( libcmis::OAuth2DataPtr oauth2 ); -+ -+ void oauth2Authenticate( ); - }; - - #endif /* _GDRIVE_SESSION_HXX_ */ -diff -ur libcmis.org/src/libcmis/http-session.hxx libcmis/src/libcmis/http-session.hxx ---- libcmis.org/src/libcmis/http-session.hxx 2021-07-27 19:09:42.582249917 +0200 -+++ libcmis/src/libcmis/http-session.hxx 2021-07-27 19:10:02.369249198 +0200 -@@ -148,7 +148,7 @@ - - void setNoSSLCertificateCheck( bool noCheck ); - -- std::string getRefreshToken( ); -+ virtual std::string getRefreshToken( ); - - protected: - HttpSession( ); -diff -ur libcmis.org/src/libcmis/oauth2-handler.cxx libcmis/src/libcmis/oauth2-handler.cxx ---- libcmis.org/src/libcmis/oauth2-handler.cxx 2021-07-27 19:09:42.582249917 +0200 -+++ libcmis/src/libcmis/oauth2-handler.cxx 2021-07-27 19:10:02.369249198 +0200 -@@ -158,6 +158,11 @@ - return m_refresh; - } - -+void OAuth2Handler::setRefreshToken( string refreshToken ) -+{ -+ m_refresh = refreshToken; -+} -+ - string OAuth2Handler::getHttpHeader( ) - { - string header; -diff -ur libcmis.org/src/libcmis/oauth2-handler.hxx libcmis/src/libcmis/oauth2-handler.hxx ---- libcmis.org/src/libcmis/oauth2-handler.hxx 2021-07-27 19:09:42.582249917 +0200 -+++ libcmis/src/libcmis/oauth2-handler.hxx 2021-07-27 19:10:02.370249198 +0200 -@@ -61,6 +61,7 @@ - - std::string getAccessToken( ) ; - std::string getRefreshToken( ) ; -+ void setRefreshToken( std::string refreshToken ) ; - - // adding HTTP auth header - std::string getHttpHeader( ) ; -diff -ur libcmis.org/src/libcmis/onedrive-session.cxx libcmis/src/libcmis/onedrive-session.cxx ---- libcmis.org/src/libcmis/onedrive-session.cxx 2021-07-27 19:09:42.583249917 +0200 -+++ libcmis/src/libcmis/onedrive-session.cxx 2021-07-27 19:10:02.370249198 +0200 -@@ -68,6 +68,45 @@ - { - } - -+void OneDriveSession::setOAuth2Data( libcmis::OAuth2DataPtr oauth2 ) -+{ -+ m_oauth2Handler = new OAuth2Handler( this, oauth2 ); -+ m_oauth2Handler->setOAuth2Parser( OAuth2Providers::getOAuth2Parser( getBindingUrl( ) ) ); -+ -+ oauth2Authenticate( ); -+} -+ -+void OneDriveSession::oauth2Authenticate() -+{ -+ // treat the supplied password as refresh token -+ if (!m_password.empty()) -+ { -+ try -+ { -+ m_inOAuth2Authentication = true; -+ -+ m_oauth2Handler->setRefreshToken(m_password); -+ // Try to get new access tokens using the stored refreshtoken -+ m_oauth2Handler->refresh(); -+ m_inOAuth2Authentication = false; -+ } -+ catch (const CurlException &e) -+ { -+ m_inOAuth2Authentication = false; -+ // refresh token expired or invalid, trigger initial auth (that in turn will hit the fallback with copy'n'paste method) -+ BaseSession::oauth2Authenticate(); -+ } -+ } -+ else -+ { -+ BaseSession::oauth2Authenticate(); -+ } -+} -+ -+string OneDriveSession::getRefreshToken() { -+ return HttpSession::getRefreshToken(); -+} -+ - libcmis::RepositoryPtr OneDriveSession::getRepository( ) - { - // Return a dummy repository since OneDrive doesn't have that notion -diff -ur libcmis.org/src/libcmis/onedrive-session.hxx libcmis/src/libcmis/onedrive-session.hxx ---- libcmis.org/src/libcmis/onedrive-session.hxx 2021-07-27 19:09:42.583249917 +0200 -+++ libcmis/src/libcmis/onedrive-session.hxx 2021-07-27 19:10:02.370249198 +0200 -@@ -62,8 +62,14 @@ - - bool isAPathMatch( Json objectJson, std::string path ); - -+ virtual std::string getRefreshToken(); -+ - private: - OneDriveSession( ); -+ -+ virtual void setOAuth2Data( libcmis::OAuth2DataPtr oauth2 ); -+ -+ void oauth2Authenticate( ); - }; - - #endif /* _ONEDRIVE_SESSION_HXX_ */ diff --git a/external/libcmis/libcmis_onedrive.patch b/external/libcmis/libcmis_onedrive.patch deleted file mode 100644 index 60d7e7b3be69..000000000000 --- a/external/libcmis/libcmis_onedrive.patch +++ /dev/null @@ -1,445 +0,0 @@ -diff --git a/src/libcmis/http-session.cxx b/src/libcmis/http-session.cxx -index 2638482..227667e 100644 ---- a/src/libcmis/http-session.cxx -+++ b/src/libcmis/http-session.cxx -@@ -293,6 +293,94 @@ libcmis::HttpResponsePtr HttpSession::httpGetRequest( string url ) - return response; - } - -+libcmis::HttpResponsePtr HttpSession::httpPatchRequest( string url, istream& is, vector< string > headers ) -+{ -+ checkOAuth2( url ); -+ -+ // Duplicate istream in case we need to retry -+ string isStr( static_cast< stringstream const&>( stringstream( ) << is.rdbuf( ) ).str( ) ); -+ -+ istringstream isOriginal( isStr ), isBackup( isStr ); -+ -+ // Reset the handle for the request -+ curl_easy_reset( m_curlHandle ); -+ initProtocols( ); -+ -+ libcmis::HttpResponsePtr response( new libcmis::HttpResponse( ) ); -+ -+ curl_easy_setopt( m_curlHandle, CURLOPT_WRITEFUNCTION, lcl_bufferData ); -+ curl_easy_setopt( m_curlHandle, CURLOPT_WRITEDATA, response->getData( ).get( ) ); -+ -+ curl_easy_setopt( m_curlHandle, CURLOPT_HEADERFUNCTION, &lcl_getHeaders ); -+ curl_easy_setopt( m_curlHandle, CURLOPT_WRITEHEADER, response.get() ); -+ -+ curl_easy_setopt( m_curlHandle, CURLOPT_MAXREDIRS, 20); -+ -+ // Get the stream length -+ is.seekg( 0, ios::end ); -+ long size = is.tellg( ); -+ is.seekg( 0, ios::beg ); -+ curl_easy_setopt( m_curlHandle, CURLOPT_INFILESIZE, size ); -+ curl_easy_setopt( m_curlHandle, CURLOPT_READDATA, &isOriginal ); -+ curl_easy_setopt( m_curlHandle, CURLOPT_READFUNCTION, lcl_readStream ); -+ curl_easy_setopt( m_curlHandle, CURLOPT_UPLOAD, 1 ); -+ curl_easy_setopt( m_curlHandle, CURLOPT_CUSTOMREQUEST, "PATCH" ); -+ curl_easy_setopt( m_curlHandle, CURLOPT_IOCTLFUNCTION, lcl_ioctlStream ); -+ curl_easy_setopt( m_curlHandle, CURLOPT_IOCTLDATA, &isOriginal ); -+ -+ // If we know for sure that 100-Continue won't be accepted, -+ // don't even try with it to save one HTTP request. -+ if ( m_no100Continue ) -+ headers.push_back( "Expect:" ); -+ try -+ { -+ httpRunRequest( url, headers ); -+ response->getData( )->finish(); -+ } -+ catch ( const CurlException& ) -+ { -+ long status = getHttpStatus( ); -+ /** If we had a HTTP 417 response, this is likely to be due to some -+ HTTP 1.0 proxy / server not accepting the "Expect: 100-continue" -+ header. Try to disable this header and try again. -+ */ -+ if ( status == 417 && !m_no100Continue) -+ { -+ // Remember that we don't want 100-Continue for the future requests -+ m_no100Continue = true; -+ response = httpPutRequest( url, isBackup, headers ); -+ } -+ -+ // If the access token is expired, we get 401 error, -+ // Need to use the refresh token to get a new one. -+ if ( status == 401 && !getRefreshToken( ).empty( ) && !m_refreshedToken ) -+ { -+ -+ // Refresh the token -+ oauth2Refresh(); -+ -+ // Resend the query -+ try -+ { -+ // Avoid infinite recursive call -+ m_refreshedToken = true; -+ response = httpPutRequest( url, isBackup, headers ); -+ m_refreshedToken = false; -+ } -+ catch (const CurlException&) -+ { -+ m_refreshedToken = false; -+ throw; -+ } -+ } -+ // Has tried but failed -+ if ( ( status != 417 || m_no100Continue ) && -+ ( status != 401 || getRefreshToken( ).empty( ) || m_refreshedToken ) ) throw; -+ } -+ m_refreshedToken = false; -+ return response; -+} -+ - libcmis::HttpResponsePtr HttpSession::httpPutRequest( string url, istream& is, vector< string > headers ) - { - checkOAuth2( url ); -diff --git a/src/libcmis/http-session.hxx b/src/libcmis/http-session.hxx -index 851d52d..29de64d 100644 ---- a/src/libcmis/http-session.hxx -+++ b/src/libcmis/http-session.hxx -@@ -132,6 +132,9 @@ class HttpSession - virtual void setOAuth2Data( libcmis::OAuth2DataPtr oauth2 ); - - libcmis::HttpResponsePtr httpGetRequest( std::string url ); -+ libcmis::HttpResponsePtr httpPatchRequest( std::string url, -+ std::istream& is, -+ std::vector< std::string > headers ); - libcmis::HttpResponsePtr httpPutRequest( std::string url, - std::istream& is, - std::vector< std::string > headers ); -diff --git a/src/libcmis/oauth2-handler.cxx b/src/libcmis/oauth2-handler.cxx -index a3320e3..842769f 100644 ---- a/src/libcmis/oauth2-handler.cxx -+++ b/src/libcmis/oauth2-handler.cxx -@@ -91,8 +91,8 @@ void OAuth2Handler::fetchTokens( string authCode ) - string post = - "code=" + authCode + - "&client_id=" + m_data->getClientId() + -- "&client_secret=" + m_data->getClientSecret() + - "&redirect_uri=" + m_data->getRedirectUri() + -+ "&scope=" + libcmis::escape( m_data->getScope() ) + - "&grant_type=authorization_code" ; - - istringstream is( post ); -@@ -121,7 +121,6 @@ void OAuth2Handler::refresh( ) - string post = - "refresh_token=" + m_refresh + - "&client_id=" + m_data->getClientId() + -- "&client_secret=" + m_data->getClientSecret() + - "&grant_type=refresh_token" ; - - istringstream is( post ); -diff --git a/src/libcmis/oauth2-providers.cxx b/src/libcmis/oauth2-providers.cxx -index 8cf9652..654021f 100644 ---- a/src/libcmis/oauth2-providers.cxx -+++ b/src/libcmis/oauth2-providers.cxx -@@ -312,7 +312,7 @@ OAuth2Parser OAuth2Providers::getOAuth2Parser( const std::string& url ) - return OAuth2Alfresco; - else if ( boost::starts_with( url, "https://www.googleapis.com/drive/v2" ) ) - return OAuth2Gdrive; -- else if ( boost::starts_with( url, "https://apis.live.net/v5.0" ) ) -+ else if ( boost::starts_with( url, "https://graph.microsoft.com/v1.0" ) ) - return OAuth2Onedrive; - - return OAuth2Gdrive; -diff --git a/src/libcmis/onedrive-document.cxx b/src/libcmis/onedrive-document.cxx -index f753b42..863a92f 100644 ---- a/src/libcmis/onedrive-document.cxx -+++ b/src/libcmis/onedrive-document.cxx -@@ -73,7 +73,7 @@ boost::shared_ptr< istream > OneDriveDocument::getContentStream( string /*stream - boost::shared_ptr< istream > stream; - string streamUrl = getStringProperty( "source" ); - if ( streamUrl.empty( ) ) -- throw libcmis::Exception( "can not found stream url" ); -+ throw libcmis::Exception( "could not find stream url" ); - - try - { -@@ -89,15 +89,15 @@ boost::shared_ptr< istream > OneDriveDocument::getContentStream( string /*stream - void OneDriveDocument::setContentStream( boost::shared_ptr< ostream > os, - string /*contentType*/, - string fileName, -- bool /*overwrite*/ ) -+ bool bReplaceExisting ) - { - if ( !os.get( ) ) - throw libcmis::Exception( "Missing stream" ); -- -+ - string metaUrl = getUrl( ); - - // Update file name meta information -- if ( !fileName.empty( ) && fileName != getContentFilename( ) ) -+ if ( bReplaceExisting && !fileName.empty( ) && fileName != getContentFilename( ) ) - { - Json metaJson; - Json fileJson( fileName.c_str( ) ); -@@ -108,7 +108,7 @@ void OneDriveDocument::setContentStream( boost::shared_ptr< ostream > os, - headers.push_back( "Content-Type: application/json" ); - try - { -- getSession()->httpPutRequest( metaUrl, is, headers ); -+ getSession()->httpPatchRequest( metaUrl, is, headers ); - } - catch ( const CurlException& e ) - { -@@ -117,9 +117,9 @@ void OneDriveDocument::setContentStream( boost::shared_ptr< ostream > os, - } - - fileName = libcmis::escape( getStringProperty( "cmis:name" ) ); -- string putUrl = getSession( )->getBindingUrl( ) + "/" + -- getStringProperty( "cmis:parentId" ) + "/files/" + -- fileName + "?overwrite=true"; -+ string putUrl = getSession( )->getBindingUrl( ) + "/me/drive/items/" + -+ getStringProperty( "cmis:parentId" ) + ":/" + -+ fileName + ":/content"; - - // Upload stream - boost::shared_ptr< istream> is ( new istream ( os->rdbuf( ) ) ); -@@ -142,6 +142,7 @@ void OneDriveDocument::setContentStream( boost::shared_ptr< ostream > os, - libcmis::DocumentPtr OneDriveDocument::checkOut( ) - { - // OneDrive doesn't have CheckOut, so just return the same document here -+ // TODO: no longer true - onedrive now has checkout/checkin - libcmis::ObjectPtr obj = getSession( )->getObject( getId( ) ); - libcmis::DocumentPtr checkout = - boost::dynamic_pointer_cast< libcmis::Document > ( obj ); -diff --git a/src/libcmis/onedrive-folder.cxx b/src/libcmis/onedrive-folder.cxx -index a9ae694..c1980c8 100644 ---- a/src/libcmis/onedrive-folder.cxx -+++ b/src/libcmis/onedrive-folder.cxx -@@ -57,7 +57,9 @@ OneDriveFolder::~OneDriveFolder( ) - vector< libcmis::ObjectPtr > OneDriveFolder::getChildren( ) - { - vector< libcmis::ObjectPtr > children; -- string query = getSession( )->getBindingUrl( ) + "/" + getId( ) + "/files"; -+ // TODO: limited to 200 items by default - to get more one would have to -+ // follow @odata.nextLink or change pagination size -+ string query = getSession( )->getBindingUrl( ) + "/me/drive/items/" + getId( ) + "/children"; - - string res; - try -@@ -70,7 +72,7 @@ vector< libcmis::ObjectPtr > OneDriveFolder::getChildren( ) - } - - Json jsonRes = Json::parse( res ); -- Json::JsonVector objs = jsonRes["data"].getList( ); -+ Json::JsonVector objs = jsonRes["value"].getList( ); - - // Create children objects from Json objects - for(unsigned int i = 0; i < objs.size(); i++) -@@ -85,8 +87,7 @@ libcmis::FolderPtr OneDriveFolder::createFolder( - const PropertyPtrMap& properties ) - { - Json propsJson = OneDriveUtils::toOneDriveJson( properties ); -- -- string uploadUrl = getSession( )->getBindingUrl( ) + "/" + getId( ); -+ string uploadUrl = getSession( )->getBindingUrl( ) + "/me/drive/items/" + getId( ) + "/children"; - - std::istringstream is( propsJson.toString( ) ); - string response; -@@ -126,9 +127,10 @@ libcmis::DocumentPtr OneDriveFolder::createDocument( - } - } - -+ // TODO: limited to 4MB, larger uploads need dedicated UploadSession - fileName = libcmis::escape( fileName ); -- string newDocUrl = getSession( )->getBindingUrl( ) + "/" + -- getId( ) + "/files/" + fileName; -+ string newDocUrl = getSession( )->getBindingUrl( ) + "/me/drive/items/" + -+ getId( ) + ":/" + fileName + ":/content"; - boost::shared_ptr< istream> is ( new istream ( os->rdbuf( ) ) ); - vector< string > headers; - string res; -diff --git a/src/libcmis/onedrive-object.cxx b/src/libcmis/onedrive-object.cxx -index 976a97b..8deb591 100644 ---- a/src/libcmis/onedrive-object.cxx -+++ b/src/libcmis/onedrive-object.cxx -@@ -65,7 +65,7 @@ void OneDriveObject::initializeFromJson ( Json json, string /*id*/, string /*nam - Json::JsonObject objs = json.getObjects( ); - Json::JsonObject::iterator it; - PropertyPtr property; -- bool isFolder = json["type"].toString( ) == "folder"; -+ bool isFolder = json["folder"].toString( ) != ""; - for ( it = objs.begin( ); it != objs.end( ); ++it) - { - property.reset( new OneDriveProperty( it->first, it->second ) ); -@@ -74,7 +74,12 @@ void OneDriveObject::initializeFromJson ( Json json, string /*id*/, string /*nam - { - property.reset( new OneDriveProperty( "cmis:contentStreamFileName", it->second ) ); - m_properties[ property->getPropertyType( )->getId()] = property; -- } -+ } else if ( it->first == "parentReference" ) { -+ if (it->second["id"].toString() != "") { -+ property.reset( new OneDriveProperty( "cmis:parentId", it->second["id"] ) ); -+ m_properties[ property->getPropertyType( )->getId()] = property; -+ } -+ } - } - - m_refreshTimestamp = time( NULL ); -@@ -122,7 +127,7 @@ void OneDriveObject::remove( bool /*allVersions*/ ) - - string OneDriveObject::getUrl( ) - { -- return getSession( )->getBindingUrl( ) + "/" + getId( ); -+ return getSession( )->getBindingUrl( ) + "/me/drive/items/" + getId( ); - } - - string OneDriveObject::getUploadUrl( ) -@@ -152,7 +157,7 @@ libcmis::ObjectPtr OneDriveObject::updateProperties( - { - vector< string > headers; - headers.push_back( "Content-Type: application/json" ); -- response = getSession( )->httpPutRequest( getUrl( ), is, headers ); -+ response = getSession( )->httpPatchRequest( getUrl( ), is, headers ); - } - catch ( const CurlException& e ) - { -diff --git a/src/libcmis/onedrive-repository.cxx b/src/libcmis/onedrive-repository.cxx -index 3eaac9c..b01f5c2 100644 ---- a/src/libcmis/onedrive-repository.cxx -+++ b/src/libcmis/onedrive-repository.cxx -@@ -35,7 +35,7 @@ OneDriveRepository::OneDriveRepository( ) : - m_description = "One Drive repository"; - m_productName = "One Drive"; - m_productVersion = "v5"; -- m_rootId = "me/skydrive"; -+ m_rootId = "/me/drive/root"; - - m_capabilities[ ACL ] = "discover"; - m_capabilities[ AllVersionsSearchable ] = "true"; -diff --git a/src/libcmis/onedrive-session.cxx b/src/libcmis/onedrive-session.cxx -index c6f4270..a603278 100644 ---- a/src/libcmis/onedrive-session.cxx -+++ b/src/libcmis/onedrive-session.cxx -@@ -79,7 +79,9 @@ libcmis::ObjectPtr OneDriveSession::getObject( string objectId ) - { - // Run the http request to get the properties definition - string res; -- string objectLink = m_bindingUrl + "/" + objectId; -+ string objectLink = m_bindingUrl + "/me/drive/items/" + objectId; -+ if (objectId == getRootId()) -+ objectLink = m_bindingUrl + objectId; - try - { - res = httpGetRequest( objectLink )->getStream()->str(); -@@ -95,12 +97,11 @@ libcmis::ObjectPtr OneDriveSession::getObject( string objectId ) - libcmis::ObjectPtr OneDriveSession::getObjectFromJson( Json& jsonRes ) - { - libcmis::ObjectPtr object; -- string kind = jsonRes["type"].toString( ); -- if ( kind == "folder" || kind == "album" ) -+ if ( jsonRes["folder"].toString() != "" ) - { - object.reset( new OneDriveFolder( this, jsonRes ) ); - } -- else if ( kind == "file" ) -+ else if ( jsonRes["file"].toString() != "" ) - { - object.reset( new OneDriveDocument( this, jsonRes ) ); - } -@@ -113,44 +114,18 @@ libcmis::ObjectPtr OneDriveSession::getObjectFromJson( Json& jsonRes ) - - libcmis::ObjectPtr OneDriveSession::getObjectByPath( string path ) - { -- string id; -- if ( path == "/" ) -- { -- id = "me/skydrive"; -- } -- else -+ string res; -+ string objectQuery = m_bindingUrl + "/me/drive/root:" + libcmis::escape( path ); -+ try - { -- path = "/SkyDrive" + path; -- size_t pos = path.rfind("/"); -- string name = libcmis::escape( path.substr( pos + 1, path.size( ) ) ); -- string res; -- string objectQuery = m_bindingUrl + "/me/skydrive/search?q=" + name; -- try -- { -- res = httpGetRequest( objectQuery )->getStream( )->str( ); -- } -- catch ( const CurlException& e ) -- { -- throw e.getCmisException( ); -- } -- Json jsonRes = Json::parse( res ); -- Json::JsonVector objs = jsonRes["data"].getList( ); -- -- // Searching for a match in the path to the object -- for ( unsigned int i = 0; i < objs.size( ); i++ ) -- { -- if ( isAPathMatch( objs[i], path ) ) -- { -- id = objs[i]["id"].toString( ); -- break; -- } -- } -+ res = httpGetRequest( objectQuery )->getStream( )->str( ); - } -- if ( id.empty( ) ) -+ catch ( const CurlException& e ) - { -- throw libcmis::Exception( "No file could be found" ); -+ throw libcmis::Exception( "No file could be found for path " + path + ": " + e.what() ); - } -- return getObject( id ); -+ Json jsonRes = Json::parse( res ); -+ return getObjectFromJson( jsonRes ); - } - - bool OneDriveSession::isAPathMatch( Json objectJson, string path ) -diff --git a/src/libcmis/onedrive-utils.cxx b/src/libcmis/onedrive-utils.cxx -index dc6ec5d..17ed324 100644 ---- a/src/libcmis/onedrive-utils.cxx -+++ b/src/libcmis/onedrive-utils.cxx -@@ -44,16 +44,16 @@ string OneDriveUtils::toCmisKey( const string& key ) - convertedKey = "cmis:createdBy"; - else if ( key == "description" ) - convertedKey = "cmis:description"; -- else if ( key == "created_time" ) -+ else if ( key == "createdDateTime" ) - convertedKey = "cmis:creationDate"; -- else if ( key == "updated_time" ) -+ else if ( key == "lastModifiedDateTime" ) - convertedKey = "cmis:lastModificationDate"; - else if ( key == "name" ) - convertedKey = "cmis:name"; - else if ( key == "size" ) - convertedKey = "cmis:contentStreamLength"; -- else if ( key == "parent_id" ) -- convertedKey = "cmis:parentId"; -+ else if ( key == "@microsoft.graph.downloadUrl" ) -+ convertedKey = "source"; - else convertedKey = key; - return convertedKey; - } -@@ -75,8 +75,6 @@ string OneDriveUtils::toOneDriveKey( const string& key ) - convertedKey = "name"; - else if ( key == "cmis:contentStreamLength" ) - convertedKey = "file_size"; -- else if ( key == "cmis:parentId" ) -- convertedKey = "parent_id"; - else convertedKey = key; - return convertedKey; - } -diff --git a/src/libcmis/session-factory.cxx b/src/libcmis/session-factory.cxx -index ba55cd9..e740afb 100644 ---- a/src/libcmis/session-factory.cxx -+++ b/src/libcmis/session-factory.cxx -@@ -71,7 +71,7 @@ namespace libcmis - session = new GDriveSession( bindingUrl, username, password, - oauth2, verbose ); - } -- else if ( bindingUrl == "https://apis.live.net/v5.0" ) -+ else if ( bindingUrl == "https://graph.microsoft.com/v1.0" ) - { - session = new OneDriveSession( bindingUrl, username, password, - oauth2, verbose); diff --git a/ucb/source/ucp/cmis/auth_provider.hxx b/ucb/source/ucp/cmis/auth_provider.hxx index 9092f3c6bd25..9ef4cdd42093 100644 --- a/ucb/source/ucp/cmis/auth_provider.hxx +++ b/ucb/source/ucp/cmis/auth_provider.hxx @@ -8,15 +8,7 @@ */ #pragma once -#if defined __GNUC__ && !defined __clang__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated" -#pragma GCC diagnostic ignored "-Wunused-but-set-parameter" -#endif #include <libcmis/libcmis.hxx> -#if defined __GNUC__ && !defined __clang__ -#pragma GCC diagnostic pop -#endif #include <com/sun/star/ucb/XCommandEnvironment.hpp> #include <cppuhelper/weakref.hxx>
