Skip to content

Commit

Permalink
Merge pull request #41 from mlibrary/http_client
Browse files Browse the repository at this point in the history
http client ping pong
  • Loading branch information
gkostin1966 authored Nov 9, 2023
2 parents 2c1c365 + 0af3a7a commit 526efbb
Show file tree
Hide file tree
Showing 14 changed files with 228 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
matrix:
suite:
- 'app'
- 'client-tests'
- 'test'
ruby:
- '3.2.2'
Expand All @@ -36,6 +37,10 @@ jobs:
run: |
docker compose build --build-arg RUBY_VERSION=${{ matrix.ruby }} app-dev
docker compose run app-dev
- if: matrix.suite == 'client-tests'
run: |
docker compose build --build-arg RUBY_VERSION=${{ matrix.ruby }} client-tests
docker compose run client-tests
- if: matrix.suite == 'test'
run: |
docker compose build --build-arg RUBY_VERSION=${{ matrix.ruby }} app apache
Expand Down
8 changes: 8 additions & 0 deletions apache/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ COPY ./apache/module /lauth/apache/module/
WORKDIR /lauth/apache/module
RUN make install

###
FROM build-base AS client-tests
COPY ./apache/client /lauth/apache/client/
RUN meson setup /lauth/apache/client/build /lauth/apache/client
WORKDIR /lauth/apache/client/build
RUN meson configure -Dtests=true && meson compile
CMD ["meson", "test", "-v"]

###
FROM module AS tests
WORKDIR /lauth/apache/build
Expand Down
15 changes: 14 additions & 1 deletion apache/client/include/lauth/api_client.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
#ifndef __LAUTH_API_CLIENT_HPP__
#define __LAUTH_API_CLIENT_HPP__

#include <memory>

#include "lauth/http_client.hpp"
#include "lauth/request.hpp"

namespace mlibrary::lauth {
class ApiClient {
public:
virtual bool isAllowed(Request req);
ApiClient() : client(std::make_unique<HttpClient>("http://localhost:9000")) {};
ApiClient(std::unique_ptr<HttpClient>&& client) : client(std::move(client)) {};
ApiClient(const ApiClient&) = delete;
ApiClient& operator=(const ApiClient&) = delete;
ApiClient(ApiClient&&) = delete;
ApiClient& operator=(const ApiClient&&) = delete;
virtual ~ApiClient() = default;

virtual bool isAllowed(Request req);

protected:
std::unique_ptr<HttpClient> client;
};
}

Expand Down
21 changes: 21 additions & 0 deletions apache/client/include/lauth/http_client.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef __LAUTH_HTTP_CLIENT_HPP__
#define __LAUTH_HTTP_CLIENT_HPP__

#include "lauth/request.hpp"

namespace mlibrary::lauth {
class HttpClient {
public:
HttpClient(const std::string& baseUrl) : baseUrl(baseUrl) {};
virtual ~HttpClient() = default;

virtual bool isAllowed(Request req);
virtual std::string get(const std::string& path);


protected:
const std::string baseUrl;
};
}

#endif // __LAUTH_HTTP_CLIENT_HPP__
36 changes: 32 additions & 4 deletions apache/client/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ lauth_includes = include_directories('include')
lauth_sources = files([
'src/lauth/api_client.cpp',
'src/lauth/authorizer.cpp',
'src/lauth/http_client.cpp',
])
lauth_tests = files([
'test/lauth/api_client_test.cpp',
'test/lauth/authorizer_test.cpp',
'test/lauth/request_test.cpp',
])

lauth_integration_tests = files([
'test/lauth/http_client_test.cpp',
])

liblauth = shared_library(
'lauth',
lauth_sources,
Expand All @@ -38,6 +43,7 @@ liblauth = shared_library(
install_headers(
'include/lauth/api_client.hpp',
'include/lauth/authorizer.hpp',
'include/lauth/http_client.hpp',
'include/lauth/request.hpp',
subdir: 'lauth')

Expand All @@ -54,21 +60,43 @@ if get_option('tests')
]
)

integration_tests = executable(
'lauth-integration-test',
lauth_sources + lauth_integration_tests,
include_directories: lauth_includes,
dependencies: [
cpp_httplib,
json,
gtest,
gmock
]
)

test('lauth-test', tests)
test('lauth-integration-test', integration_tests)
endif

os = host_machine.system()
if os == 'darwin'
http_check_links = []
httplib_links = []
else
http_check_links = ['-lssl', '-lcrypto']
httplib_links = ['-lssl', '-lcrypto']
endif

http_check = executable(
executable(
'http-service',
files(['test/mock_service.cpp']),
dependencies: [
cpp_httplib,
],
link_args: httplib_links
)

executable(
'http-check',
files(['src/http_check.cpp']),
dependencies: [
cpp_httplib,
],
link_args: http_check_links
link_args: httplib_links
)
5 changes: 1 addition & 4 deletions apache/client/src/lauth/api_client.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
#include "lauth/api_client.hpp"

// #include <string>

namespace mlibrary::lauth {
bool ApiClient::isAllowed(Request req) {
return req.user.size() > 0;
// bool result = http_client(req.uri, req.user);
return client->isAllowed(req);
}
}

14 changes: 14 additions & 0 deletions apache/client/src/lauth/http_client.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "lauth/http_client.hpp"

#include <httplib.h>

namespace mlibrary::lauth {
std::string HttpClient::get(const std::string& path) {
httplib::Client client(baseUrl);

auto res = client.Get(path);

return res->body;
}
}

46 changes: 36 additions & 10 deletions apache/client/test/lauth/api_client_test.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,40 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "mocks.hpp"

using testing::_;
using ::testing::_;
using ::testing::Return;

#include "lauth/api_client.hpp"
#include "lauth/request.hpp"

using namespace mlibrary::lauth;

TEST(ApiClient, a_request_with_no_user_is_denied) {
TEST(ApiClientTest, allowed_by_mock) {
auto client = std::make_unique<MockHttpClient>();
EXPECT_CALL(*client, isAllowed(_)).WillOnce(Return(true));
ApiClient api_client(std::move(client));

Request req {};

auto allowed = api_client.isAllowed(req);

EXPECT_THAT(allowed, true);
}

TEST(ApiClientTest, denied_by_mock) {
auto client = std::make_unique<MockHttpClient>();
EXPECT_CALL(*client, isAllowed(_)).WillOnce(Return(false));
ApiClient api_client(std::move(client));

Request req {};

auto allowed = api_client.isAllowed(req);

EXPECT_THAT(allowed, false);
}

TEST(ApiClientTest, a_request_with_no_user_is_denied) {
ApiClient client;
Request request;

Expand All @@ -17,7 +43,7 @@ TEST(ApiClient, a_request_with_no_user_is_denied) {
}


TEST(ApiClient, a_request_with_authorized_user_is_allowed) {
TEST(ApiClientTest, a_request_with_authorized_user_is_allowed) {
ApiClient client;
Request request;

Expand All @@ -26,11 +52,11 @@ TEST(ApiClient, a_request_with_authorized_user_is_allowed) {
EXPECT_THAT(result, true);
}

// TEST(ApiClient, a_request_with_unauthorized_user_is_denied) {
// ApiClient client;
// Request request;
TEST(ApiClientTest, a_request_with_unauthorized_user_is_denied) {
ApiClient client;
Request request;

// request.user = "unauthorized";
// bool result = client.isAllowed(request);
// EXPECT_THAT(result, false);
// }
request.user = "unauthorized";
bool result = client.isAllowed(request);
EXPECT_THAT(result, false);
}
27 changes: 27 additions & 0 deletions apache/client/test/lauth/http_client_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>

using testing::_;

#include <httplib.h>

#include "lauth/http_client.hpp"
#include "lauth/request.hpp"

using namespace mlibrary::lauth;

const std::string api_url = "http://localhost:9000";

TEST(HttpClient, get_request_returns_body) {
HttpClient client(api_url);

std::string response = client.get("/");
EXPECT_THAT(response, "Root");
}

TEST(HttpClient, get_request_with_path_returns_body) {
HttpClient client(api_url);

std::string response = client.get("/ping");
EXPECT_THAT(response, "pong");
}
10 changes: 9 additions & 1 deletion apache/client/test/lauth/mocks.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#ifndef _LAUTH_TEST_MOCKS_HPP_
#define _LAUTH_TEST_MOCKS_HPP_

#include <lauth/api_client.hpp>
#include "lauth/api_client.hpp"
#include "lauth/http_client.hpp"

using namespace mlibrary::lauth;

Expand All @@ -10,4 +11,11 @@ class MockApiClient : public ApiClient {
MOCK_METHOD(bool, isAllowed, (Request), (override));
};

class MockHttpClient : public HttpClient {
public:
MockHttpClient() : HttpClient("http://localhost:9000") {};
MOCK_METHOD(bool, isAllowed, (Request), (override));
MOCK_METHOD(std::string, get, (const std::string&), (override));
};

#endif
2 changes: 1 addition & 1 deletion apache/client/test/lauth/request_test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <lauth/request.hpp>
#include <gtest/gtest.h>

TEST(Request, is_ok) {
TEST(RequestTest, is_ok) {
EXPECT_EQ(1, 1);
}
42 changes: 42 additions & 0 deletions apache/client/test/mock_service.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <httplib.h>

int main(int argc, char **argv) {
using namespace httplib;

int port;
const std::string address = "0.0.0.0";
Server server;

if (argc == 2) {
port = std::atoi(argv[1]);
server.bind_to_port(address, port);
} else {
port = server.bind_to_any_port(address);
}

server.Get("/", [](const Request &req, Response &res) {
res.set_content("Root", "text/plain");
});

server.Get("/ping", [](const Request &req, Response &res) {
res.set_content("pong", "text/plain");
});

server.Get("/stop", [&](const Request &req, Response &res) {
res.set_content("Shutting down server...", "text/plain");
server.stop();
});

server.Get("/users/:id/is_allowed", [](const Request &req, Response &res) {
auto user_id = req.path_params.at("id");
std::cout << "Got request for /users/:id/is_allowed" << std::endl;
res.set_content("no", "text/plain");
});

std::cout << "Listening on http://" << address << ":" << port << std::endl;
std::cout << "Stop URL: http://" << address << ":" << port << "/stop"
<< std::endl;
server.listen_after_bind();
std::cout << "Server has stopped... Bye!" << std::endl;
return 0;
}
17 changes: 17 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,23 @@ services:
- ./apache/module:/lauth/apache/module
- build_cache:/lauth/apache/build

mock-api:
build:
context: ./
dockerfile: ./apache/Dockerfile
target: tests
profiles: ["integration"]
ports:
- "127.0.0.1:9000:9000"
command: ["./http-service", "9000"]

client-tests:
build:
context: ./
dockerfile: ./apache/Dockerfile
target: client-tests
profiles: ["test"]

test:
profiles: ["test"]
build:
Expand Down
2 changes: 1 addition & 1 deletion test/restrictions/umich_login_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
end
end

context "when logged in as an authorized user" do
xcontext "when logged in as an authorized user" do
it "is allowed" do
response = website.get("/user/") do |req|
req.headers["Authorization"] = basic_auth_good_user
Expand Down

0 comments on commit 526efbb

Please sign in to comment.