diff options
author | Henry Castro <hcastro@collabora.com> | 2017-08-03 17:05:48 -0400 |
---|---|---|
committer | Henry Castro <hcastro@collabora.com> | 2017-08-03 17:11:00 -0400 |
commit | a262b7d7ba4a8ff9832446849662a5516e53db53 (patch) | |
tree | 410c684a73b1f1d507a30803ed5a93562507bf4c | |
parent | loleaflet: graphic selection can get misplaced if mouse is moved fast (diff) | |
download | online-a262b7d7ba4a8ff9832446849662a5516e53db53.tar.gz online-a262b7d7ba4a8ff9832446849662a5516e53db53.zip |
wsd: OAuth token passing
MS-WOPI:
"The following HTTP header MUST be included in all WOPI requests."
"Authorization "Bearer" and <token>"
Change-Id: Ie5327286e93b86a49a0248ff5886bf3ea99df768
-rw-r--r-- | test/Makefile.am | 4 | ||||
-rw-r--r-- | test/UnitOAuth.cpp | 149 | ||||
-rw-r--r-- | wsd/Storage.cpp | 3 |
3 files changed, 155 insertions, 1 deletions
diff --git a/test/Makefile.am b/test/Makefile.am index f7f4c090cc..237c2e1a20 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -16,7 +16,7 @@ noinst_LTLIBRARIES = \ unit-timeout.la unit-prefork.la \ unit-storage.la unit-client.la \ unit-admin.la unit-tilecache.la \ - unit-fuzz.la unit-oob.la + unit-fuzz.la unit-oob.la unit-oauth.la MAGIC_TO_FORCE_SHLIB_CREATION = -rpath /dummy AM_LDFLAGS = -pthread -module $(MAGIC_TO_FORCE_SHLIB_CREATION) $(ZLIB_LIBS) @@ -62,6 +62,8 @@ unit_timeout_la_SOURCES = UnitTimeout.cpp unit_prefork_la_SOURCES = UnitPrefork.cpp unit_storage_la_SOURCES = UnitStorage.cpp unit_tilecache_la_SOURCES = UnitTileCache.cpp +unit_oauth_la_SOURCES = UnitOAuth.cpp +unit_oauth_la_LIBADD = $(CPPUNIT_LIBS) if HAVE_LO_PATH SYSTEM_STAMP = @SYSTEMPLATE_PATH@/system_stamp diff --git a/test/UnitOAuth.cpp b/test/UnitOAuth.cpp new file mode 100644 index 0000000000..2a24ed9b22 --- /dev/null +++ b/test/UnitOAuth.cpp @@ -0,0 +1,149 @@ +/* -*- 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/. + */ + +#include "config.h" + +//#include "Exceptions.hpp" +#include "Log.hpp" +#include "Unit.hpp" +#include "helpers.hpp" +#include <Poco/JSON/Object.h> +#include <Poco/LocalDateTime.h> +#include <Poco/DateTimeFormat.h> +#include <Poco/DateTimeFormatter.h> +#include <Poco/Net/HTTPRequest.h> +#include <Poco/Net/HTTPResponse.h> +#include <Poco/Net/HTTPServer.h> +#include <Poco/Net/HTTPRequestHandlerFactory.h> +#include <Poco/Net/HTTPRequestHandler.h> +#include <Poco/Net/HTTPServerRequest.h> +#include <Poco/Net/HTTPServerResponse.h> +#include <Poco/Net/HTTPServerParams.h> +#include <Poco/Net/ServerSocket.h> +#include <Poco/Net/OAuth20Credentials.h> + +using Poco::DateTimeFormatter; +using Poco::DateTimeFormat; +using Poco::JSON::Object; +using Poco::Net::HTTPServer; +using Poco::Net::HTTPRequest; +using Poco::Net::HTTPResponse; +using Poco::Net::HTTPRequestHandlerFactory; +using Poco::Net::HTTPRequestHandler; +using Poco::Net::HTTPServerRequest; +using Poco::Net::HTTPServerResponse; +using Poco::Net::HTTPServerParams; +using Poco::Net::OAuth20Credentials; +using Poco::Net::ServerSocket; + +class WopiHostRequestHandler: public HTTPRequestHandler +{ +public: + void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) + { + Poco::URI uriReq(request.getURI()); + + // The resource server MUST validate the access token + // and ensure that it has not expired and that its scope + // covers the requested resource. + OAuth20Credentials creds(request); + assert (creds.getBearerToken() == "s3hn3ct0k3v"); + + // CheckFileInfo + if (uriReq.getPath() == "/wopi/files/0") + { + Poco::LocalDateTime now; + Object::Ptr fileInfo = new Object(); + fileInfo->set("BaseFileName", "empty.odt"); + fileInfo->set("Size", "1024"); + fileInfo->set("Version", "1.0"); + fileInfo->set("OwnerId", "test"); + fileInfo->set("UserId", "test"); + fileInfo->set("UserFriendlyName", "test"); + fileInfo->set("UserCanWrite", "true"); + fileInfo->set("PostMessageOrigin", "localhost"); + fileInfo->set("LastModifiedTime", DateTimeFormatter::format(now, DateTimeFormat::ISO8601_FORMAT)); + + std::ostringstream oss; + fileInfo->stringify(oss); + response.setContentType("application/json; charset=utf-8"); + std::ostream& ostr = response.send(); + ostr << oss.str(); + } + // GetFile + else if (uriReq.getPath() == "/wopi/files/0/contents") + { + response.sendFile(Poco::Path(TDOC, "empty.odt").toString(), "application/vnd.oasis.opendocument.text"); + response.setStatusAndReason(HTTPResponse::HTTP_OK); + } + } + +}; + +class WopiHostRequestHandlerFactory: public HTTPRequestHandlerFactory +{ +public: + HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& /*request*/) + { + return new WopiHostRequestHandler(); + } +}; + + +class UnitOAuth : public UnitWSD +{ +public: + UnitOAuth() + { + } + + virtual void configure(Poco::Util::LayeredConfiguration& /*config*/) override + { + } + + void invokeTest() override + { + HTTPResponse response; + ServerSocket wopiSocket(0); + HTTPServerParams* wopiParams = new HTTPServerParams(); + wopiParams->setKeepAlive(false); + HTTPServer fakeWopiHost(new WopiHostRequestHandlerFactory, wopiSocket, wopiParams); + fakeWopiHost.start(); + + std::string WopiSrc; + const std::string testName = "UnitOAuth "; + + // RFC 6749 + // 7. Accessing Protected Resources + // The client accesses protected resources by presenting the access + // token (access_token) to the resource server. + Poco::URI wopiURL("http://localhost/wopi/files/0?access_token=s3hn3ct0k3v"); + wopiURL.setPort(wopiSocket.address().port()); + Poco::URI::encode(wopiURL.toString(), ":/?", WopiSrc); + Poco::URI loolUri(helpers::getTestServerURI()); + HTTPRequest request(HTTPRequest::HTTP_GET, "lool/" + WopiSrc + "/ws"); + + auto socket = helpers::connectLOKit(loolUri, request, response); + helpers::sendTextFrame(socket, "load url=" + WopiSrc, testName); + + const auto status = helpers::assertResponseString(socket, "status:", testName); + + Poco::Thread::sleep(1000); + fakeWopiHost.stop(); + + exitTest(TestResult::Ok); + } +}; + +UnitBase *unit_create_wsd(void) +{ + return new UnitOAuth(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp index 23a2dfdfad..b64b6431a7 100644 --- a/wsd/Storage.cpp +++ b/wsd/Storage.cpp @@ -501,6 +501,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const st Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uriObject.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1); request.set("User-Agent", WOPI_AGENT_STRING); + request.set("Authorization", "Bearer " + accessToken); addStorageDebugCookie(request); psession->sendRequest(request); @@ -603,6 +604,7 @@ std::string WopiStorage::loadStorageFileToLocal(const std::string& accessToken) Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uriObject.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1); request.set("User-Agent", WOPI_AGENT_STRING); + request.set("Authorization", "Bearer " + accessToken); addStorageDebugCookie(request); psession->sendRequest(request); @@ -672,6 +674,7 @@ StorageBase::SaveResult WopiStorage::saveLocalFileToStorage(const std::string& a Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, uriObject.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1); request.set("X-WOPI-Override", "PUT"); + request.set("Authorization", "Bearer " + accessToken); if (!_forceSave) { // Request WOPI host to not overwrite if timestamps mismatch |