loolwsd/Admin.cpp      |   33 ++------------
 loolwsd/FileServer.hpp |  114 +++++++++++++++++++++++++++++--------------------
 2 files changed, 74 insertions(+), 73 deletions(-)

New commits:
commit 204a9c742f921816a1a5b658a40d9f43390223ac
Author: Jan Holesovsky <ke...@collabora.com>
Date:   Wed Apr 6 20:14:03 2016 +0200

    loolwsd: Allow asking for credentials even during websocket setup.
    
    It may happen that admin.html is cached, which leads to the cookie not being
    set up, which then leads to endless amount of attempts to log in.

diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp
index 275434e..83d0312 100644
--- a/loolwsd/Admin.cpp
+++ b/loolwsd/Admin.cpp
@@ -30,6 +30,7 @@
 #include "Admin.hpp"
 #include "AdminModel.hpp"
 #include "Common.hpp"
+#include "FileServer.hpp"
 #include "TileCache.hpp"
 #include "Storage.hpp"
 #include "LOOLProtocol.hpp"
@@ -347,34 +348,10 @@ void 
AdminRequestHandler::handleRequest(HTTPServerRequest& request, HTTPServerRe
 
         if (request.find("Upgrade") != request.end() && 
Poco::icompare(request["Upgrade"], "websocket") == 0)
         {
-            if (request.find("Cookie") != request.end())
-            {
-                // FIXME: Handle other cookie params like '; httponly; secure'
-                const std::size_t pos = request["Cookie"].find_first_of("=");
-                if (pos == std::string::npos)
-                    throw Poco::Net::NotAuthenticatedException("Missing JWT");
-
-                const std::string jwtToken = request["Cookie"].substr(pos + 1);
-                Log::info("Verifying JWT token: " + jwtToken);
-                // TODO: Read key from configuration file
-                const std::string keyPath = "/etc/loolwsd/" + 
std::string(SSL_KEY_FILE);
-                JWTAuth authAgent(keyPath, "admin", "admin", "admin");
-                if (authAgent.verify(jwtToken))
-                {
-                    Log::trace("JWT token is valid");
-                    handleWSRequests(request, response, nSessionId);
-                }
-                else
-                {
-                    Log::info("Invalid JWT token");
-                    throw Poco::Net::NotAuthenticatedException("Invalid 
Token");
-                }
-            }
-            else
-            {
-                Log::info("Missing authentication cookie. Handshake 
declined.");
-                throw Poco::Net::NotAuthenticatedException("Missing token");
-            }
+            if (!FileServerRequestHandler::isAdminLoggedIn(request, response))
+                throw Poco::Net::NotAuthenticatedException("Invalid admin 
login");
+
+            handleWSRequests(request, response, nSessionId);
         }
     }
     catch(const Poco::Net::NotAuthenticatedException& exc)
diff --git a/loolwsd/FileServer.hpp b/loolwsd/FileServer.hpp
index c1c8dd7..52d4429 100644
--- a/loolwsd/FileServer.hpp
+++ b/loolwsd/FileServer.hpp
@@ -48,6 +48,55 @@ using Poco::Util::Application;
 class FileServerRequestHandler: public HTTPRequestHandler
 {
 public:
+    /// Evaluate if the cookie exists, and if not, ask for the credentials.
+    static bool isAdminLoggedIn(HTTPServerRequest& request, 
HTTPServerResponse& response)
+    {
+        if (request.find("Cookie") != request.end())
+        {
+            // FIXME: Handle other cookie params like '; httponly; secure'
+            const std::size_t pos = request["Cookie"].find_first_of("=");
+            if (pos == std::string::npos)
+                throw Poco::Net::NotAuthenticatedException("Missing JWT");
+
+            const std::string jwtToken = request["Cookie"].substr(pos + 1);
+            Log::info("Verifying JWT token: " + jwtToken);
+            // TODO: Read key from configuration file
+            const std::string keyPath = "/etc/loolwsd/" + 
std::string(SSL_KEY_FILE);
+            JWTAuth authAgent(keyPath, "admin", "admin", "admin");
+            if (authAgent.verify(jwtToken))
+            {
+                Log::trace("JWT token is valid");
+                return true;
+            }
+
+            Log::info("Invalid JWT token, let the administrator re-login");
+        }
+
+        HTTPBasicCredentials credentials(request);
+
+        // TODO: Read username and password from config file
+        if (credentials.getUsername() == "admin"
+                && credentials.getPassword() == "admin")
+        {
+            const std::string htmlMimeType = "text/html";
+            // generate and set the cookie
+            // TODO: Read key from configuration file
+            const std::string keyPath = "/etc/loolwsd/" + 
std::string(SSL_KEY_FILE);
+            JWTAuth authAgent(keyPath, "admin", "admin", "admin");
+            const std::string jwtToken = authAgent.getAccessToken();
+            Poco::Net::HTTPCookie cookie("jwt", jwtToken);
+            cookie.setPath("/adminws/");
+            cookie.setSecure(true);
+            cookie.setHttpOnly(true);
+            response.addCookie(cookie);
+
+            return true;
+        }
+
+        Log::info("Wrong admin credentials.");
+        return false;
+    }
+
     void handleRequest(HTTPServerRequest& request, HTTPServerResponse& 
response) override
     {
         try
@@ -62,57 +111,32 @@ public:
 
             if (request.getMethod() == HTTPRequest::HTTP_GET)
             {
-                // FIXME: Some nice way to ask for credentials for protected 
files
                 if (endPoint == "admin.html" ||
                     endPoint == "adminSettings.html" ||
                     endPoint == "adminAnalytics.html")
                 {
-                    HTTPBasicCredentials credentials(request);
-                    // TODO: Read username and password from config file
-                    if (credentials.getUsername() == "admin"
-                        && credentials.getPassword() == "admin")
-                    {
-                        const std::string htmlMimeType = "text/html";
-                        // generate and set the cookie
-                        // TODO: Read key from configuration file
-                        const std::string keyPath = "/etc/loolwsd/" + 
std::string(SSL_KEY_FILE);
-                        JWTAuth authAgent(keyPath, "admin", "admin", "admin");
-                        const std::string jwtToken = 
authAgent.getAccessToken();
-                        Poco::Net::HTTPCookie cookie("jwt", jwtToken);
-                        cookie.setPath("/adminws/");
-                        cookie.setSecure(true);
-                        cookie.setHttpOnly(true);
-                        response.addCookie(cookie);
-                        response.setContentType(htmlMimeType);
-                        response.sendFile(LOOLWSD::FileServerRoot + 
requestUri.getPath(), htmlMimeType);
-                    }
-                    else
-                    {
-                        Log::info("Wrong admin credentials.");
-                        throw Poco::Net::NotAuthenticatedException("Wrong 
credentials.");
-                    }
+                    if (!FileServerRequestHandler::isAdminLoggedIn(request, 
response))
+                        throw Poco::Net::NotAuthenticatedException("Invalid 
admin login");
                 }
+
+                const std::string filePath = requestUri.getPath();
+                const std::size_t extPoint = endPoint.find_last_of(".");
+                if (extPoint == std::string::npos)
+                    throw Poco::FileNotFoundException("Invalid file.");
+
+                const std::string fileType = endPoint.substr(extPoint + 1);
+                std::string mimeType;
+                if (fileType == "js")
+                    mimeType = "application/javascript";
+                else if (fileType == "css")
+                    mimeType = "text/css";
+                else if (fileType == "html")
+                    mimeType = "text/html";
                 else
-                {
-                    const std::string filePath = requestUri.getPath();
-                    const std::size_t extPoint = endPoint.find_last_of(".");
-                    if (extPoint == std::string::npos)
-                        throw Poco::FileNotFoundException("Invalid file.");
-
-                    const std::string fileType = endPoint.substr(extPoint + 1);
-                    std::string mimeType;
-                    if (fileType == "js")
-                        mimeType = "application/javascript";
-                    else if (fileType == "css")
-                        mimeType = "text/css";
-                    else if (fileType == "html")
-                        mimeType = "text/html";
-                    else
-                        mimeType = "text/plain";
-
-                    response.setContentType(mimeType);
-                    response.sendFile(LOOLWSD::FileServerRoot + 
requestUri.getPath(), mimeType);
-                }
+                    mimeType = "text/plain";
+
+                response.setContentType(mimeType);
+                response.sendFile(LOOLWSD::FileServerRoot + 
requestUri.getPath(), mimeType);
             }
         }
         catch (Poco::Net::NotAuthenticatedException& exc)
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to