Skip to content

Commit

Permalink
Create RBAC Policies with IDs (#33)
Browse files Browse the repository at this point in the history
Allow creating RBAC policies with custom IDs
  • Loading branch information
kw510 authored Jul 7, 2023
1 parent f0b5a1f commit 0645ce6
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 3 deletions.
19 changes: 19 additions & 0 deletions src/datastore/rbac-policies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,23 @@ std::vector<RbacPolicy> RbacPolicy::Record::check() const {

return policies;
}

RbacPolicy RetrieveRbacPolicy(const std::string &id) {
std::string_view qry = R"(
select
_id,
_rev,
name
from "rbac-policies"
where
_id = $1::text;
)";

auto res = pg::exec(qry, id);
if (res.empty()) {
throw err::DatastoreRbacPolicyNotFound();
}

return RbacPolicy(res[0]);
}
} // namespace datastore
2 changes: 2 additions & 0 deletions src/datastore/rbac-policies.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,6 @@ class RbacPolicy {
};

using RbacPolicies = std::vector<RbacPolicy>;

RbacPolicy RetrieveRbacPolicy(const std::string &id);
} // namespace datastore
18 changes: 16 additions & 2 deletions src/service/grpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,21 @@ grpc::ServerUnaryReactor *Grpc::CreateRbacPolicy(
gk::v1::RbacPolicy *response) {
auto *reactor = context->DefaultReactor();

if (request->has_id()) {
try {
auto policy = datastore::RetrieveRbacPolicy(request->id());
reactor->Finish(grpc::Status(grpc::StatusCode::ALREADY_EXISTS, "Duplicate policy id"));
return reactor;
} catch (const err::DatastoreRbacPolicyNotFound &) {
// Policy with an `id` matching the request `id` doesn't exist, we can continue with
// creating a new one.
} catch (const std::exception &e) {
std::cout << "Y " << e.what() << std::endl;
reactor->Finish(grpc::Status(grpc::StatusCode::UNAVAILABLE, "Failed to retrieve data"));
return reactor;
}
}

auto policy = map(request);
try {
// Store the policy
Expand Down Expand Up @@ -444,8 +459,7 @@ grpc::ServerUnaryReactor *Grpc::CreateRbacPolicy(
}
}
}

} catch (...) {
} catch (std::exception &e) {
reactor->Finish(grpc::Status(grpc::StatusCode::UNAVAILABLE, "Failed to store data"));
return reactor;
}
Expand Down
38 changes: 37 additions & 1 deletion src/service/grpc_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -908,8 +908,44 @@ TEST_F(GrpcTest, UpdateIndentity) {
}

// RBAC
TEST_F(GrpcTest, CreateRbacRbacPolicy) {
TEST_F(GrpcTest, CreateRbacPolicy) {
service::Grpc service;
// Success: create rbac policy with `id`
{
grpc::CallbackServerContext ctx;
grpc::testing::DefaultReactorTestPeer peer(&ctx);
gk::v1::RbacPolicy response;

gk::v1::CreateRbacPolicyRequest request;
request.set_id("id:GrpcTest.CreateRbacPolicy-id");
request.set_name("name:GrpcTest.CreateRbacPolicy-id");

auto reactor = service.CreateRbacPolicy(&ctx, &request, &response);
EXPECT_TRUE(peer.test_status_set());
EXPECT_TRUE(peer.test_status().ok());
EXPECT_EQ(peer.reactor(), reactor);
EXPECT_EQ(request.id(), response.id());
EXPECT_EQ(request.name(), response.name());
}

// Error: duplicate `id`
{
const datastore::RbacPolicy policy({.name = "name:GrpcTest.CreateRbacPolicy-duplicate"});
EXPECT_NO_THROW(policy.store());

grpc::CallbackServerContext ctx;
grpc::testing::DefaultReactorTestPeer peer(&ctx);
gk::v1::RbacPolicy response;

gk::v1::CreateRbacPolicyRequest request;
request.set_id(policy.id());
request.set_name("name:GrpcTest.CreateRbacPolicy-duplicate");

auto reactor = service.CreateRbacPolicy(&ctx, &request, &response);
EXPECT_TRUE(peer.test_status_set());
EXPECT_EQ(grpc::StatusCode::ALREADY_EXISTS, peer.test_status().error_code());
EXPECT_EQ("Duplicate policy id", peer.test_status().error_message());
}

// Success: create rbac policy
{
Expand Down

0 comments on commit 0645ce6

Please sign in to comment.