From 455ccdf33c4580eb9ac3e71152fa8854266b7fbc Mon Sep 17 00:00:00 2001 From: Ed Tanous Date: Fri, 10 Feb 2023 12:14:47 -0800 Subject: Remove security headers middleware test We haven't had security middleware for a long time. Signed-off-by: Ed Tanous Change-Id: Ie8b2803139921eda6168495ab3b0b39b0cb34fa7 --- src/crow_test.cpp | 938 ---------------------------- src/security_headers_middleware_test.cpp | 86 --- src/token_authorization_middleware_test.cpp | 312 --------- 3 files changed, 1336 deletions(-) delete mode 100644 src/crow_test.cpp delete mode 100644 src/security_headers_middleware_test.cpp delete mode 100644 src/token_authorization_middleware_test.cpp (limited to 'src') diff --git a/src/crow_test.cpp b/src/crow_test.cpp deleted file mode 100644 index 1f8360f01c..0000000000 --- a/src/crow_test.cpp +++ /dev/null @@ -1,938 +0,0 @@ -#include "crow.h" - -#include -#include -#include - -#include "gtest/gtest.h" - -using namespace std; -using namespace crow; - -bool failed__ = false; -void error_print() -{ - cerr << endl; -} - -template -void error_print(const A& a, Args... args) -{ - cerr << a; - error_print(args...); -} - -template -void fail(Args... args) -{ - error_print(args...); - failed__ = true; -} - -#define ASSERT_EQUAL(a, b) \ - if ((a) != (b)) \ - fail(__FILE__ ":", __LINE__, ": Assert fail: expected ", (a), " actual ", \ - (b), ", " #a " == " #b ", at " __FILE__ ":", __LINE__) -#define ASSERT_NOTEQUAL(a, b) \ - if ((a) == (b)) \ - fail(__FILE__ ":", __LINE__, ": Assert fail: not expected ", (a), \ - ", " #a " != " #b ", at " __FILE__ ":", __LINE__) - -#define DISABLE_TEST(x) \ - struct test##x \ - { \ - void test(); \ - } x##_; \ - void test##x::test() - -#define LOCALHOST_ADDRESS "127.0.0.1" - -TEST(Crow, Rule) -{ - TaggedRule<> r("/http/"); - r.name("abc"); - - // empty handler - fail to validate - try - { - r.validate(); - fail("empty handler should fail to validate"); - } - catch (const runtime_error& e) - {} - - int x = 0; - - // registering handler - r([&x] { - x = 1; - return ""; - }); - - r.validate(); - - Response res; - - // executing handler - ASSERT_EQUAL(0, x); - boost::beast::http::request req{}; - r.handle(Request(req), res, RoutingParams()); - ASSERT_EQUAL(1, x); - - // registering handler with Request argument - r([&x](const crow::Request&) { - x = 2; - return ""; - }); - - r.validate(); - - // executing handler - ASSERT_EQUAL(1, x); - r.handle(Request(req), res, RoutingParams()); - ASSERT_EQUAL(2, x); -} - -TEST(Crow, ParameterTagging) -{ - static_assert(black_magic::isValid(""), "valid url"); - static_assert(!black_magic::isValid(""), "invalid url"); - static_assert(!black_magic::isValid("nt>"), "invalid url"); - ASSERT_EQUAL(1, black_magic::getParameterTag("")); - ASSERT_EQUAL(2, black_magic::getParameterTag("")); - ASSERT_EQUAL(3, black_magic::getParameterTag("")); - ASSERT_EQUAL(3, black_magic::getParameterTag("")); - ASSERT_EQUAL(4, black_magic::getParameterTag("")); - ASSERT_EQUAL(4, black_magic::getParameterTag("")); - ASSERT_EQUAL(5, black_magic::getParameterTag("")); - ASSERT_EQUAL(6 * 6 + 6 + 1, - black_magic::getParameterTag("")); - ASSERT_EQUAL(6 * 6 + 6 + 2, - black_magic::getParameterTag("")); - ASSERT_EQUAL(6 * 6 + 6 * 3 + 2, - black_magic::getParameterTag("")); - - // url definition parsed in compile time, build into *one number*, and given - // to template argument - static_assert( - std::is_same, - black_magic::Arguments<6 * 6 + 6 * 3 + 2>::type>::value, - "tag to type container"); -} - -TEST(Crow, PathRouting) -{ - SimpleApp app; - - BMCWEB_ROUTE(app, "/file") - ([] { return "file"; }); - - BMCWEB_ROUTE(app, "/path/") - ([] { return "path"; }); - - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - - req.url = "/file"; - - app.handle(req, res); - - ASSERT_EQUAL(200, res.resultInt()); - } - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - - req.url = "/file/"; - - app.handle(req, res); - ASSERT_EQUAL(404, res.resultInt()); - } - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - - req.url = "/path"; - - app.handle(req, res); - ASSERT_NOTEQUAL(404, res.resultInt()); - } - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - - req.url = "/path/"; - - app.handle(req, res); - ASSERT_EQUAL(200, res.resultInt()); - } -} - -TEST(Crow, RoutingTest) -{ - SimpleApp app; - int A{}; - uint32_t b{}; - double C{}; - string D{}; - string E{}; - - BMCWEB_ROUTE(app, "/0/") - ([&](uint32_t b) { - b = b; - return "OK"; - }); - - BMCWEB_ROUTE(app, "/1//") - ([&](int a, uint32_t b) { - A = a; - b = b; - return "OK"; - }); - - BMCWEB_ROUTE(app, "/4////") - ([&](int a, uint32_t b, double c, string d) { - A = a; - b = b; - C = c; - D = d; - return "OK"; - }); - - BMCWEB_ROUTE(app, "/5/////") - ([&](int a, uint32_t b, double c, string d, string e) { - A = a; - b = b; - C = c; - D = d; - E = e; - return "OK"; - }); - - app.validate(); - // app.debugPrint(); - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - - req.url = "/-1"; - - app.handle(req, res); - - ASSERT_EQUAL(404, res.resultInt()); - } - - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - - req.url = "/0/1001999"; - - app.handle(req, res); - - ASSERT_EQUAL(200, res.resultInt()); - - ASSERT_EQUAL(1001999, b); - } - - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - - req.url = "/1/-100/1999"; - - app.handle(req, res); - - ASSERT_EQUAL(200, res.resultInt()); - - ASSERT_EQUAL(-100, A); - ASSERT_EQUAL(1999, b); - } - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - - req.url = "/4/5000/3/-2.71828/hellhere"; - - app.handle(req, res); - - ASSERT_EQUAL(200, res.resultInt()); - - ASSERT_EQUAL(5000, A); - ASSERT_EQUAL(3, b); - ASSERT_EQUAL(-2.71828, C); - ASSERT_EQUAL("hellhere", D); - } - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - - req.url = "/5/-5/999/3.141592/hello_there/a/b/c/d"; - - app.handle(req, res); - - ASSERT_EQUAL(200, res.resultInt()); - - ASSERT_EQUAL(-5, A); - ASSERT_EQUAL(999, b); - ASSERT_EQUAL(3.141592, C); - ASSERT_EQUAL("hello_there", D); - ASSERT_EQUAL("a/b/c/d", E); - } -} - -TEST(Crow, simple_response_RoutingParams) -{ - ASSERT_EQUAL(100, - Response(boost::beast::http::status::continue_).resultInt()); - ASSERT_EQUAL(200, Response("Hello there").resultInt()); - ASSERT_EQUAL(500, - Response(boost::beast::http::status::internal_server_error, - "Internal Error?") - .resultInt()); - - RoutingParams rp; - rp.intParams.push_back(1); - rp.intParams.push_back(5); - rp.uintParams.push_back(2); - rp.doubleParams.push_back(3); - rp.stringParams.push_back("hello"); - ASSERT_EQUAL(1, rp.get(0)); - ASSERT_EQUAL(5, rp.get(1)); - ASSERT_EQUAL(2, rp.get(0)); - ASSERT_EQUAL(3, rp.get(0)); - ASSERT_EQUAL("hello", rp.get(0)); -} - -TEST(Crow, handler_with_response) -{ - SimpleApp app; - BMCWEB_ROUTE(app, "/")([](const crow::Request&, crow::Response&) {}); -} - -TEST(Crow, http_method) -{ - SimpleApp app; - - BMCWEB_ROUTE(app, "/").methods(boost::beast::http::verb::post, - boost::beast::http::verb::get)( - [](const Request& req) { - if (req.method() == boost::beast::http::verb::get) - return "2"; - else - return "1"; - }); - - BMCWEB_ROUTE(app, "/get_only") - .methods(boost::beast::http::verb::get)( - [](const Request& /*req*/) { return "get"; }); - BMCWEB_ROUTE(app, "/post_only") - .methods(boost::beast::http::verb::post)( - [](const Request& /*req*/) { return "post"; }); - - // cannot have multiple handlers for the same url - // BMCWEB_ROUTE(app, "/") - //.methods(boost::beast::http::verb::get) - //([]{ return "2"; }); - - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - - req.url = "/"; - app.handle(req, res); - - ASSERT_EQUAL("2", res.body()); - } - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - - req.url = "/"; - r.method(boost::beast::http::verb::post); - app.handle(req, res); - - ASSERT_EQUAL("1", res.body()); - } - - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - - req.url = "/get_only"; - app.handle(req, res); - - ASSERT_EQUAL("get", res.body()); - } - - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - - req.url = "/get_only"; - r.method(boost::beast::http::verb::post); - app.handle(req, res); - - ASSERT_NOTEQUAL("get", res.body()); - } -} - -TEST(Crow, server_handling_error_request) -{ - static char buf[2048]; - SimpleApp app; - BMCWEB_ROUTE(app, "/")([] { return "A"; }); - Server server(&app, LOCALHOST_ADDRESS, 45451); - auto _ = async(launch::async, [&] { server.run(); }); - std::string sendmsg = "POX"; - asio::io_context is; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - - c.send(asio::buffer(sendmsg)); - - try - { - c.receive(asio::buffer(buf, 2048)); - fail(); - } - catch (const std::exception& e) - { - // std::cerr << e.what() << std::endl; - } - } - server.stop(); -} - -TEST(Crow, multi_server) -{ - static char buf[2048]; - SimpleApp app1, app2; - BMCWEB_ROUTE(app1, "/").methods(boost::beast::http::verb::get, - boost::beast::http::verb::post)( - [] { return "A"; }); - BMCWEB_ROUTE(app2, "/").methods(boost::beast::http::verb::get, - boost::beast::http::verb::post)( - [] { return "B"; }); - - Server server1(&app1, LOCALHOST_ADDRESS, 45451); - Server server2(&app2, LOCALHOST_ADDRESS, 45452); - - auto _ = async(launch::async, [&] { server1.run(); }); - auto _2 = async(launch::async, [&] { server2.run(); }); - - std::string sendmsg = - "POST /\r\nContent-Length:3\r\nX-HeaderTest: 123\r\n\r\nA=b\r\n"; - asio::io_context is; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - - c.send(asio::buffer(sendmsg)); - - size_t recved = c.receive(asio::buffer(buf, 2048)); - ASSERT_EQUAL('A', buf[recved - 1]); - } - - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45452)); - - for (auto ch : sendmsg) - { - char buf[1] = {ch}; - c.send(asio::buffer(buf)); - } - - size_t recved = c.receive(asio::buffer(buf, 2048)); - ASSERT_EQUAL('b', buf[recved - 1]); - } - - server1.stop(); - server2.stop(); -} - -TEST(Crow, black_magic) -{ - using namespace black_magic; - static_assert( - std::is_same::type>::value, - "LastElementType"); - static_assert( - std::is_same::rebind::type>::value, - "pop_back"); - static_assert( - std::is_same::rebind::rebind< - LastElementType>::type>::value, - "pop_back"); -} - -struct NullMiddleware -{ - struct Context - {}; - - template - void beforeHandle(Request&, Response&, Context&, AllContext&) - {} - - template - void afterHandle(Request&, Response&, Context&, AllContext&) - {} -}; - -struct NullSimpleMiddleware -{ - struct Context - {}; - - void beforeHandle(Request& /*req*/, Response& /*res*/, Context& /*ctx*/) - {} - - void afterHandle(Request& /*req*/, Response& /*res*/, Context& /*ctx*/) - {} -}; - -TEST(Crow, middleware_simple) -{ - App app; - decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451); - BMCWEB_ROUTE(app, "/") - ([&](const crow::Request& req) { - app.getContext(req); - app.getContext(req); - return ""; - }); -} - -struct IntSettingMiddleware -{ - struct Context - { - int val; - }; - - template - void beforeHandle(Request&, Response&, Context& ctx, AllContext&) - { - ctx.val = 1; - } - - template - void afterHandle(Request&, Response&, Context& ctx, AllContext&) - { - ctx.val = 2; - } -}; - -std::vector test_middleware_context_vector; - -struct FirstMW -{ - struct Context - { - std::vector v; - }; - - void beforeHandle(Request& /*req*/, Response& /*res*/, Context& ctx) - { - ctx.v.push_back("1 before"); - } - - void afterHandle(Request& /*req*/, Response& /*res*/, Context& ctx) - { - ctx.v.push_back("1 after"); - test_middleware_context_vector = ctx.v; - } -}; - -struct SecondMW -{ - struct Context - {}; - template - void beforeHandle(Request& req, Response& res, Context&, - AllContext& all_ctx) - { - all_ctx.template get().v.push_back("2 before"); - if (req.url == "/break") - res.end(); - } - - template - void afterHandle(Request&, Response&, Context&, AllContext& all_ctx) - { - all_ctx.template get().v.push_back("2 after"); - } -}; - -struct ThirdMW -{ - struct Context - {}; - template - void beforeHandle(Request&, Response&, Context&, AllContext& all_ctx) - { - all_ctx.template get().v.push_back("3 before"); - } - - template - void afterHandle(Request&, Response&, Context&, AllContext& all_ctx) - { - all_ctx.template get().v.push_back("3 after"); - } -}; - -TEST(Crow, middlewareContext) -{ - static char buf[2048]; - // SecondMW depends on FirstMW (it uses all_ctx.get) - // so it leads to compile error if we remove FirstMW from definition - // App app; - // or change the order of FirstMW and SecondMW - // App app; - - App app; - - int x{}; - BMCWEB_ROUTE(app, "/") - ([&](const Request& req) { - { - auto& ctx = app.getContext(req); - x = ctx.val; - } - { - auto& ctx = app.getContext(req); - ctx.v.push_back("handle"); - } - - return ""; - }); - BMCWEB_ROUTE(app, "/break") - ([&](const Request& req) { - { - auto& ctx = app.getContext(req); - ctx.v.push_back("handle"); - } - - return ""; - }); - - decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451); - auto _ = async(launch::async, [&] { server.run(); }); - std::string sendmsg = "GET /\r\n\r\n"; - asio::io_context is; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - - c.send(asio::buffer(sendmsg)); - - c.receive(asio::buffer(buf, 2048)); - c.close(); - } - { - auto& out = test_middleware_context_vector; - ASSERT_EQUAL(1, x); - ASSERT_EQUAL(7, out.size()); - ASSERT_EQUAL("1 before", out[0]); - ASSERT_EQUAL("2 before", out[1]); - ASSERT_EQUAL("3 before", out[2]); - ASSERT_EQUAL("handle", out[3]); - ASSERT_EQUAL("3 after", out[4]); - ASSERT_EQUAL("2 after", out[5]); - ASSERT_EQUAL("1 after", out[6]); - } - std::string sendmsg2 = "GET /break\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - - c.send(asio::buffer(sendmsg2)); - - c.receive(asio::buffer(buf, 2048)); - c.close(); - } - { - auto& out = test_middleware_context_vector; - ASSERT_EQUAL(4, out.size()); - ASSERT_EQUAL("1 before", out[0]); - ASSERT_EQUAL("2 before", out[1]); - ASSERT_EQUAL("2 after", out[2]); - ASSERT_EQUAL("1 after", out[3]); - } - server.stop(); -} - -TEST(Crow, bug_quick_repeated_request) -{ - static char buf[2048]; - - SimpleApp app; - - BMCWEB_ROUTE(app, "/")([&] { return "hello"; }); - - decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451); - auto _ = async(launch::async, [&] { server.run(); }); - std::string sendmsg = "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n"; - asio::io_context is; - { - std::vector> v; - for (int i = 0; i < 5; i++) - { - v.push_back(async(launch::async, [&] { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - - for (int j = 0; j < 5; j++) - { - c.send(asio::buffer(sendmsg)); - - size_t received = c.receive(asio::buffer(buf, 2048)); - ASSERT_EQUAL("hello", std::string(buf + received - 5, - buf + received)); - } - c.close(); - })); - } - } - server.stop(); -} - -TEST(Crow, simple_url_params) -{ - static char buf[2048]; - - SimpleApp app; - - QueryString lastUrlParams; - - BMCWEB_ROUTE(app, "/params") - ([&lastUrlParams](const crow::Request& req) { - lastUrlParams = std::move(req.urlParams); - return "OK"; - }); - - /// params?h=1&foo=bar&lol&count[]=1&count[]=4&pew=5.2 - - decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451); - auto _ = async(launch::async, [&] { server.run(); }); - asio::io_context is; - std::string sendmsg; - - // check empty params - sendmsg = "GET /params\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - stringstream ss; - ss << lastUrlParams; - - ASSERT_EQUAL("[ ]", ss.str()); - } - // check single presence - sendmsg = "GET /params?foobar\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - ASSERT_TRUE(lastUrlParams.get("missing") == nullptr); - ASSERT_TRUE(lastUrlParams.get("foobar") != nullptr); - ASSERT_TRUE(lastUrlParams.getList("missing").empty()); - } - // check multiple presence - sendmsg = "GET /params?foo&bar&baz\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - ASSERT_TRUE(lastUrlParams.get("missing") == nullptr); - ASSERT_TRUE(lastUrlParams.get("foo") != nullptr); - ASSERT_TRUE(lastUrlParams.get("bar") != nullptr); - ASSERT_TRUE(lastUrlParams.get("baz") != nullptr); - } - // check single value - sendmsg = "GET /params?hello=world\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - ASSERT_EQUAL(string(lastUrlParams.get("hello")), "world"); - } - // check multiple value - sendmsg = "GET /params?hello=world&left=right&up=down\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - ASSERT_EQUAL(string(lastUrlParams.get("hello")), "world"); - ASSERT_EQUAL(string(lastUrlParams.get("left")), "right"); - ASSERT_EQUAL(string(lastUrlParams.get("up")), "down"); - } - // check multiple value, multiple types - sendmsg = "GET /params?int=100&double=123.45&boolean=1\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - ASSERT_EQUAL(boost::lexical_cast(lastUrlParams.get("int")), 100); - ASSERT_EQUAL(boost::lexical_cast(lastUrlParams.get("double")), - 123.45); - ASSERT_EQUAL(boost::lexical_cast(lastUrlParams.get("boolean")), - true); - } - // check single array value - sendmsg = "GET /params?tmnt[]=leonardo\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - ASSERT_TRUE(lastUrlParams.get("tmnt") == nullptr); - ASSERT_EQUAL(lastUrlParams.getList("tmnt").size(), 1); - ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[0]), "leonardo"); - } - // check multiple array value - sendmsg = - "GET /params?tmnt[]=leonardo&tmnt[]=donatello&tmnt[]=raphael\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - - ASSERT_EQUAL(lastUrlParams.getList("tmnt").size(), 3); - ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[0]), "leonardo"); - ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[1]), "donatello"); - ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[2]), "raphael"); - } - server.stop(); -} - -TEST(Crow, routeDynamic) -{ - SimpleApp app; - int x = 1; - app.routeDynamic("/")([&] { - x = 2; - return ""; - }); - - app.routeDynamic("/set4")([&](const Request&) { - x = 4; - return ""; - }); - app.routeDynamic("/set5")([&](const Request&, Response& res) { - x = 5; - res.end(); - }); - - app.routeDynamic("/set_int/")([&](int y) { - x = y; - return ""; - }); - - try - { - app.routeDynamic("/invalid_test//")([]() { return ""; }); - fail(); - } - catch (const std::exception&) - {} - - // app is in an invalid state when routeDynamic throws an exception. - try - { - app.validate(); - fail(); - } - catch (const std::exception&) - {} - - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - req.url = "/"; - app.handle(req, res); - ASSERT_EQUAL(x, 2); - } - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - req.url = "/set_int/42"; - app.handle(req, res); - ASSERT_EQUAL(x, 42); - } - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - req.url = "/set5"; - app.handle(req, res); - ASSERT_EQUAL(x, 5); - } - { - boost::beast::http::request r{}; - Request req{r}; - Response res; - req.url = "/set4"; - app.handle(req, res); - ASSERT_EQUAL(x, 4); - } -} diff --git a/src/security_headers_middleware_test.cpp b/src/security_headers_middleware_test.cpp deleted file mode 100644 index 99f1f5b370..0000000000 --- a/src/security_headers_middleware_test.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "app.hpp" - -#include - -#include -#include - -using namespace crow; -using namespace std; - -// Tests that the security headers are added correctly -TEST(SecurityHeaders, TestHeadersExist) -{ - App app; - app.bindaddr("127.0.0.1").port(45451); - BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; }); - auto _ = async(launch::async, [&] { app.run(); }); - - asio::io_context is; - std::array buf; - std::string sendmsg; - - { - // Retry a couple of times waiting for the server to come up - // TODO(ed) This is really unfortunate, and should use some form of - // mock - asio::ip::tcp::socket c(is); - for (int i = 0; i < 200; i++) - { - try - { - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string("127.0.0.1"), 45451)); - c.close(); - break; - } - catch (const std::exception& e) - { - // do nothing. We expect this to fail while the server is - // starting up - } - } - } - - // Test correct login credentials - sendmsg = "GET /\r\n\r\n"; - - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string("127.0.0.1"), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf)); - c.close(); - auto return_code = std::string(&buf[9], &buf[12]); - EXPECT_EQ("200", return_code); - std::string response(std::begin(buf), std::end(buf)); - - // This is a routine to split strings until a blank is hit - // TODO(ed) this should really use the HTTP parser - std::vector headers; - std::string::size_type pos = 0; - std::string::size_type prev = 0; - while ((pos = response.find("\r\n", prev)) != std::string::npos) - { - auto this_string = response.substr(prev, pos - prev); - if (this_string == "") - { - break; - } - headers.push_back(this_string); - prev = pos + 2; - } - headers.push_back(response.substr(prev)); - - EXPECT_EQ(headers[0], "HTTP/1.1 200 OK"); - EXPECT_THAT(headers, ::testing::Contains("Strict-Transport-Security: " - "max-age=31536000; " - "includeSubdomains; preload")); - EXPECT_THAT(headers, ::testing::Contains("X-UA-Compatible: IE=11")); - EXPECT_THAT(headers, ::testing::Contains("X-Frame-Options: DENY")); - EXPECT_THAT(headers, - ::testing::Contains("X-XSS-Protection: 1; mode=block")); - EXPECT_THAT(headers, ::testing::Contains( - "X-Content-Security-Policy: default-src 'self'")); - app.stop(); -} diff --git a/src/token_authorization_middleware_test.cpp b/src/token_authorization_middleware_test.cpp deleted file mode 100644 index a93f8c8ff3..0000000000 --- a/src/token_authorization_middleware_test.cpp +++ /dev/null @@ -1,312 +0,0 @@ -#include "token_authorization_middleware.hpp" - -#include -#include -#include - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using namespace crow; - -class TokenAuth : public ::testing::Test -{ - public: - TokenAuth() : - lk(std::unique_lock(m)), - io(std::make_shared()) - {} - - std::mutex m; - std::condition_variable cv; - std::unique_lock lk; - std::shared_ptr io; - int testPort = 45451; -}; - -TEST_F(TokenAuth, SpecialResourcesAreAcceptedWithoutAuth) -{ - App app(io); - crow::token_authorization::requestRoutes(app); - BMCWEB_ROUTE(app, "/redfish/v1") - ([]() { return boost::beast::http::status::ok; }); - auto _ = std::async(std::launch::async, [&] { - app.port(testPort).run(); - cv.notify_one(); - io->run(); - }); - - asio::io_context is; - std::string sendmsg; - - static char buf[2048]; - - // Homepage should be passed with no credentials - sendmsg = "GET /\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string("127.0.0.1"), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - EXPECT_EQ("200", std::string(buf + 9, buf + 12)); - } - - // static should be passed with no credentials - sendmsg = "GET /static/index.html\r\n\r\n"; - { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string("127.0.0.1"), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - EXPECT_EQ("404", std::string(buf + 9, buf + 12)); - } - - app.stop(); -} - -// Tests that Base64 basic strings work -TEST(TokenAuthentication, TestRejectedResource) -{ - App app; - app.bindaddr("127.0.0.1").port(45451); - BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; }); - auto _ = async(std::launch::async, [&] { app.run(); }); - - asio::io_context is; - static char buf[2048]; - - // Other resources should not be passed - std::string sendmsg = "GET /foo\r\n\r\n"; - asio::ip::tcp::socket c(is); - for (int i = 0; i < 200; i++) - { - try - { - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string("127.0.0.1"), 45451)); - } - catch (const std::exception& e) - { - // do nothing - } - } - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - EXPECT_EQ("401", std::string(buf + 9, buf + 12)); - - app.stop(); -} - -// Tests that Base64 basic strings work -TEST(TokenAuthentication, TestGetLoginUrl) -{ - App app; - app.bindaddr("127.0.0.1").port(45451); - BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; }); - auto _ = async(std::launch::async, [&] { app.run(); }); - - asio::io_context is; - static char buf[2048]; - - // Other resources should not be passed - std::string sendmsg = "GET /login\r\n\r\n"; - asio::ip::tcp::socket c(is); - for (int i = 0; i < 200; i++) - { - try - { - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string("127.0.0.1"), 45451)); - } - catch (const std::exception& e) - { - // do nothing - } - } - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf, 2048)); - c.close(); - EXPECT_EQ("401", std::string(buf + 9, buf + 12)); - - app.stop(); -} - -// Tests boundary conditions on login -TEST(TokenAuthentication, TestPostBadLoginUrl) -{ - App app; - app.bindaddr("127.0.0.1").port(45451); - BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; }); - auto _ = async(std::launch::async, [&] { app.run(); }); - - asio::io_context is; - std::array buf; - std::string sendmsg; - - auto send_to_localhost = [&is, &buf](std::string sendmsg) { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string("127.0.0.1"), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf)); - c.close(); - }; - - { - // Retry a couple of times waiting for the server to come up - asio::ip::tcp::socket c(is); - for (int i = 0; i < 200; i++) - { - try - { - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string("127.0.0.1"), 45451)); - c.close(); - break; - } - catch (const std::exception& e) - { - // do nothing. We expect this to fail while the server is - // starting up - } - } - } - - // Test blank login credentials - sendmsg = "POST /login\r\nContent-Length:0\r\n\r\n\r\n"; - { - send_to_localhost(sendmsg); - auto return_code = std::string(&buf[9], &buf[12]); - EXPECT_EQ("400", return_code); - } - - // Test wrong login credentials - sendmsg = "POST /login\r\nContent-Length:38\r\n\r\n{\"username\": \"foo\", " - "\"password\": \"bar\"}\r\n"; - { - send_to_localhost(sendmsg); - auto return_code = std::string(&buf[9], &buf[12]); - EXPECT_EQ("401", return_code); - // TODO(ed) need to test more here. Response string? - } - - // Test only sending a username - sendmsg = - "POST /login\r\nContent-Length:19\r\n\r\n{\"username\": \"foo\"}\r\n"; - { - send_to_localhost(sendmsg); - auto return_code = std::string(&buf[9], &buf[12]); - EXPECT_EQ("400", return_code); - } - - // Test only sending a password - sendmsg = - "POST /login\r\nContent-Length:19\r\n\r\n{\"password\": \"foo\"}\r\n"; - { - send_to_localhost(sendmsg); - auto return_code = std::string(&buf[9], &buf[12]); - EXPECT_EQ("400", return_code); - } - - app.stop(); -} - -// Test class that allows login for a fixed password. -class KnownLoginAuthenticator -{ - public: - inline bool authenticate(const std::string& username, - const std::string& password) - { - return (username == "dude") && (password == "foo"); - } -}; - -TEST(TokenAuthentication, TestSuccessfulLogin) -{ - App app; - app.bindaddr("127.0.0.1").port(45451); - BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; }); - auto _ = async(std::launch::async, [&] { app.run(); }); - - asio::io_context is; - std::array buf; - std::string sendmsg; - - auto send_to_localhost = [&is, &buf](std::string sendmsg) { - asio::ip::tcp::socket c(is); - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string("127.0.0.1"), 45451)); - c.send(asio::buffer(sendmsg)); - c.receive(asio::buffer(buf)); - c.close(); - }; - - { - // Retry a couple of times waiting for the server to come up - asio::ip::tcp::socket c(is); - for (int i = 0; i < 200; i++) - { - try - { - c.connect(asio::ip::tcp::endpoint( - asio::ip::address::from_string("127.0.0.1"), 45451)); - c.close(); - break; - } - catch (const std::exception& e) - { - // do nothing. We expect this to fail while the server is - // starting up - } - } - } - - // Test correct login credentials - sendmsg = - "POST /login\r\nContent-Length:40\r\n\r\n{\"username\": \"dude\", " - "\"password\": \"foo\"}\r\n"; - { - send_to_localhost(sendmsg); - std::string response(std::begin(buf), std::end(buf)); - // This is a routine to split strings until a newline is hit - // TODO(ed) this should really use the HTTP parser - std::vector headers; - std::string::size_type pos = 0; - std::string::size_type prev = 0; - int content_length = 0; - std::string content_encoding(""); - while ((pos = response.find("\r\n", prev)) != std::string::npos) - { - auto this_string = response.substr(prev, pos - prev); - if (this_string == "") - { - prev = pos + 2; - break; - } - - headers.push_back(this_string); - prev = pos + 2; - } - EXPECT_EQ(headers[0], "HTTP/1.1 200 OK"); - EXPECT_THAT(headers, - testing::Contains("Content-Type: application/json")); - auto http_content = response.substr(prev); - } - - // Try to use those login credentials to access a resource - sendmsg = "GET /\r\nAuthorization: token\r\n\r\n{\"username\": \"dude\", " - "\"password\": \"dude\"}\r\n"; - { - send_to_localhost(sendmsg); - auto return_code = std::string(&buf[9], &buf[12]); - EXPECT_EQ("200", return_code); - } - - app.stop(); -} -- cgit v1.2.3