void HTTPResponseTest::testCookies() { HTTPResponse response; HTTPCookie cookie1("cookie1", "value1"); response.addCookie(cookie1); std::vector<HTTPCookie> cookies; response.getCookies(cookies); assert (cookies.size() == 1); assert (cookie1.getVersion() == cookies[0].getVersion()); assert (cookie1.getName() == cookies[0].getName()); assert (cookie1.getValue() == cookies[0].getValue()); assert (cookie1.getComment() == cookies[0].getComment()); assert (cookie1.getDomain() == cookies[0].getDomain()); assert (cookie1.getPath() == cookies[0].getPath()); assert (cookie1.getSecure() == cookies[0].getSecure()); assert (cookie1.getMaxAge() == cookies[0].getMaxAge()); HTTPCookie cookie2("cookie2", "value2"); cookie2.setVersion(1); cookie2.setMaxAge(42); cookie2.setSecure(true); response.addCookie(cookie2); response.getCookies(cookies); assert (cookies.size() == 2); HTTPCookie cookie2a; if (cookies[0].getName() == cookie2.getName()) cookie2a = cookies[0]; else cookie2a = cookies[1]; assert (cookie2.getVersion() == cookie2a.getVersion()); assert (cookie2.getName() == cookie2a.getName()); assert (cookie2.getValue() == cookie2a.getValue()); assert (cookie2.getComment() == cookie2a.getComment()); assert (cookie2.getDomain() == cookie2a.getDomain()); assert (cookie2.getPath() == cookie2a.getPath()); assert (cookie2.getSecure() == cookie2a.getSecure()); assert (cookie2.getMaxAge() == cookie2a.getMaxAge()); HTTPResponse response2; response2.add("Set-Cookie", "name1=value1"); response2.add("Set-cookie", "name2=value2"); cookies.clear(); response2.getCookies(cookies); assert (cookies.size() == 2); assert (cookies[0].getName() == "name1" && cookies[1].getName() == "name2" || cookies[0].getName() == "name2" && cookies[1].getName() == "name1"); }
bool FileServerRequestHandler::isAdminLoggedIn(const HTTPRequest& request, HTTPResponse &response) { assert(LOOLWSD::AdminEnabled); const auto& config = Application::instance().config(); NameValueCollection cookies; request.getCookies(cookies); try { const std::string jwtToken = cookies.get("jwt"); LOG_INF("Verifying JWT token: " << jwtToken); JWTAuth authAgent("admin", "admin", "admin"); if (authAgent.verify(jwtToken)) { LOG_TRC("JWT token is valid"); return true; } LOG_INF("Invalid JWT token, let the administrator re-login"); } catch (const Poco::Exception& exc) { LOG_INF("No existing JWT cookie found"); } // If no cookie found, or is invalid, let the admin re-login HTTPBasicCredentials credentials(request); const std::string& userProvidedUsr = credentials.getUsername(); const std::string& userProvidedPwd = credentials.getPassword(); // Deny attempts to login without providing a username / pwd and fail right away // We don't even want to allow a password-less PAM module to be used here, // or anything. if (userProvidedUsr.empty() || userProvidedPwd.empty()) { LOG_WRN("An attempt to log into Admin Console without username or password."); return false; } // Check if the user is allowed to use the admin console if (config.getBool("admin_console.enable_pam", "false")) { // use PAM - it needs the username too if (!isPamAuthOk(userProvidedUsr, userProvidedPwd)) return false; } else { // use the hash or password in the config file if (!isConfigAuthOk(userProvidedUsr, userProvidedPwd)) return false; } // authentication passed, generate and set the cookie JWTAuth authAgent("admin", "admin", "admin"); const std::string jwtToken = authAgent.getAccessToken(); Poco::Net::HTTPCookie cookie("jwt", jwtToken); // bundlify appears to add an extra /dist -> dist/dist/admin cookie.setPath(LOOLWSD::ServiceRoot + "/loleaflet/dist/"); cookie.setSecure(LOOLWSD::isSSLEnabled() || LOOLWSD::isSSLTermination()); response.addCookie(cookie); return true; }