Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Audit Logging] Logger and factory APIs in C-Core and C++. #32750

Merged
merged 53 commits into from
Apr 26, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
5f36c9b
audit logging APIs
rockspore Mar 29, 2023
1ef7536
const functions
rockspore Mar 29, 2023
d73779e
fix include guards
rockspore Mar 29, 2023
5fa99bc
move .cc to src/cpp/server
rockspore Mar 29, 2023
8a75d02
trailing newline
rockspore Mar 29, 2023
e77a037
changed the design
rockspore Mar 30, 2023
c6b1174
add register impl in C++
rockspore Mar 30, 2023
6ab33b3
remove extra include
rockspore Mar 30, 2023
c623c9e
newlines
rockspore Mar 30, 2023
3b85b67
include port_platform
rockspore Mar 30, 2023
ba8b7ae
move API headers inside for now
rockspore Apr 7, 2023
f9b7748
Merge branch 'master' of https://github.com/grpc/grpc into audit-log-api
rockspore Apr 7, 2023
eb82b4e
put current src into BUILD targets
rockspore Apr 7, 2023
c7776d3
generate projects
rockspore Apr 7, 2023
579fb6b
virtual dtors, etc
rockspore Apr 10, 2023
ccb3a0c
BUILD
rockspore Apr 10, 2023
70098a0
virtual dtors
rockspore Apr 10, 2023
b323fc8
generate projects
rockspore Apr 10, 2023
03a449a
iwyu
rockspore Apr 10, 2023
f98b12d
external deps in BUILD
rockspore Apr 10, 2023
dc3f3b8
iwyu again
rockspore Apr 10, 2023
0d2fcb5
ctor for audit context
rockspore Apr 10, 2023
07365a4
sanity check
rockspore Apr 10, 2023
c5a8598
add tests and move APIs to public headers
rockspore Apr 11, 2023
fc810a3
generate projects
rockspore Apr 11, 2023
8e8faec
fix iwyu
rockspore Apr 11, 2023
c83b7f0
remove grpc_audit_logging.h from GRPC_PUBLIC_HDRS
rockspore Apr 11, 2023
ced9d10
remove unused params
rockspore Apr 11, 2023
8f536de
remove wrapping in C++
rockspore Apr 19, 2023
f68d735
Merge branch 'master' of github.com:grpc/grpc into audit-log-api
rockspore Apr 19, 2023
81ef1ed
comments and iwyu
rockspore Apr 19, 2023
8af53a5
iwyu
rockspore Apr 19, 2023
ee874d4
add external deps to grpc_public_hdrs
rockspore Apr 20, 2023
2e575a2
comments
rockspore Apr 21, 2023
5dc1b6b
move definition into .cc
rockspore Apr 21, 2023
57c4044
make registry getter private
rockspore Apr 21, 2023
daa86a5
generate projects
rockspore Apr 21, 2023
8e5f24d
remove naked include
rockspore Apr 21, 2023
e32af2b
fix BUILD
rockspore Apr 21, 2023
930d88b
generate projects
rockspore Apr 21, 2023
8664063
fix cpp header
rockspore Apr 21, 2023
a8295ed
constexpr the register func
rockspore Apr 21, 2023
6f6acd1
no lint for unused using decls
rockspore Apr 21, 2023
127f12e
add factory existence API
rockspore Apr 21, 2023
df129cc
change registry's parsing API
rockspore Apr 21, 2023
974bb05
remove extraneous directory and file
rockspore Apr 24, 2023
d426f9d
address comments
rockspore Apr 24, 2023
06bb361
remove naked include
rockspore Apr 24, 2023
7e51701
Automated change: Fix sanity tests
rockspore Apr 24, 2023
6e4b0ec
Merge pull request #13 from rockspore/create-pull-request/patch-06bb361
rockspore Apr 24, 2023
2f3b29b
change to static members
rockspore Apr 25, 2023
dee212e
change to pointers
rockspore Apr 25, 2023
e019b5c
remove naked include
rockspore Apr 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
64 changes: 34 additions & 30 deletions src/core/lib/security/authorization/audit_logging.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <memory>
#include <utility>

#include "absl/base/thread_annotations.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_format.h"
Expand All @@ -39,62 +40,65 @@
namespace grpc_core {
namespace experimental {

void AuditLoggerRegistry::RegisterAuditLoggerFactory(
namespace {

Mutex* g_mu = new Mutex();
AuditLoggerRegistry* g_registry ABSL_GUARDED_BY(g_mu) =
new AuditLoggerRegistry();

} // namespace

void AuditLoggerRegistry::RegisterFactory(
std::unique_ptr<AuditLoggerFactory> factory) {
auto& registry = GetAuditLoggerRegistry();
MutexLock lock(&registry.mu_);
registry.logger_factories_map_[factory->name()] = std::move(factory);
if (factory == nullptr) return;
markdroth marked this conversation as resolved.
Show resolved Hide resolved
MutexLock lock(g_mu);
GPR_ASSERT(g_registry->logger_factories_map_.find(factory->name()) ==
markdroth marked this conversation as resolved.
Show resolved Hide resolved
g_registry->logger_factories_map_.end());
g_registry->logger_factories_map_[factory->name()] = std::move(factory);
}

bool AuditLoggerRegistry::AuditLoggerFactoryExists(absl::string_view name) {
auto& registry = AuditLoggerRegistry::GetAuditLoggerRegistry();
MutexLock lock(&registry.mu_);
return registry.logger_factories_map_.find(name) !=
registry.logger_factories_map_.end();
bool AuditLoggerRegistry::FactoryExists(absl::string_view name) {
MutexLock lock(g_mu);
return g_registry->logger_factories_map_.find(name) !=
g_registry->logger_factories_map_.end();
}

absl::StatusOr<std::unique_ptr<AuditLoggerFactory::Config>>
AuditLoggerRegistry::ParseAuditLoggerConfig(absl::string_view name,
const Json& json) {
auto factory_or = AuditLoggerRegistry::GetAuditLoggerFactory(name);
AuditLoggerRegistry::ParseConfig(absl::string_view name, const Json& json) {
MutexLock lock(g_mu);
auto factory_or = g_registry->GetAuditLoggerFactory(name);
if (!factory_or.ok()) {
return absl::InvalidArgumentError("unsupported audit logger type");
return factory_or.status();
}
return factory_or.value()->ParseAuditLoggerConfig(json);
}

std::unique_ptr<AuditLogger> AuditLoggerRegistry::CreateAuditLogger(
std::unique_ptr<AuditLoggerFactory::Config> config) {
auto factory_or = AuditLoggerRegistry::GetAuditLoggerFactory(config->name());
MutexLock lock(g_mu);
auto factory_or = g_registry->GetAuditLoggerFactory(config->name());
GPR_ASSERT(factory_or.ok());
return factory_or.value()->CreateAuditLogger(std::move(config));
markdroth marked this conversation as resolved.
Show resolved Hide resolved
}

AuditLoggerRegistry& AuditLoggerRegistry::GetAuditLoggerRegistry() {
static AuditLoggerRegistry& registry = *new AuditLoggerRegistry();
return registry;
}

absl::StatusOr<AuditLoggerFactory*> AuditLoggerRegistry::GetAuditLoggerFactory(
absl::string_view name) {
markdroth marked this conversation as resolved.
Show resolved Hide resolved
auto& registry = GetAuditLoggerRegistry();
MutexLock lock(&registry.mu_);
auto it = registry.logger_factories_map_.find(name);
if (it != registry.logger_factories_map_.end()) {
return it->second.get();
auto it = logger_factories_map_.find(name);
if (it == logger_factories_map_.end()) {
return absl::NotFoundError(
absl::StrFormat("audit logger factory for %s does not exist", name));
}
return absl::NotFoundError(
absl::StrFormat("audit logger factory %s does not exist", name));
return it->second.get();
}

void AuditLoggerRegistry::TestOnlyResetRegistry() {
auto& registry = GetAuditLoggerRegistry();
MutexLock lock(&registry.mu_);
registry.logger_factories_map_.clear();
MutexLock lock(g_mu);
delete g_registry;
g_registry = new AuditLoggerRegistry();
}

void RegisterAuditLoggerFactory(std::unique_ptr<AuditLoggerFactory> factory) {
AuditLoggerRegistry::RegisterAuditLoggerFactory(std::move(factory));
AuditLoggerRegistry::RegisterFactory(std::move(factory));
}

} // namespace experimental
Expand Down
20 changes: 7 additions & 13 deletions src/core/lib/security/authorization/audit_logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,26 @@
#include <map>
#include <memory>

#include "absl/base/thread_annotations.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"

#include <grpc/grpc_audit_logging.h>

#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/json/json.h"

namespace grpc_core {
namespace experimental {

class AuditLoggerRegistry {
public:
static void RegisterAuditLoggerFactory(std::unique_ptr<AuditLoggerFactory>);
AuditLoggerRegistry() = default;

static void RegisterFactory(std::unique_ptr<AuditLoggerFactory>);

static bool AuditLoggerFactoryExists(absl::string_view name);
static bool FactoryExists(absl::string_view name);

static absl::StatusOr<std::unique_ptr<AuditLoggerFactory::Config>>
ParseAuditLoggerConfig(absl::string_view name, const Json& json);
ParseConfig(absl::string_view name, const Json& json);

// This assume the given config is parsed and validated already.
// Therefore, it should always succeed in creating a logger.
Expand All @@ -56,18 +56,12 @@ class AuditLoggerRegistry {
static void TestOnlyResetRegistry();

private:
AuditLoggerRegistry() = default;

static AuditLoggerRegistry& GetAuditLoggerRegistry();

static absl::StatusOr<AuditLoggerFactory*> GetAuditLoggerFactory(
absl::StatusOr<AuditLoggerFactory*> GetAuditLoggerFactory(
absl::string_view name);

Mutex mu_;

// The key is owned by the factory.
std::map<absl::string_view, std::unique_ptr<AuditLoggerFactory>>
logger_factories_map_ ABSL_GUARDED_BY(mu_);
logger_factories_map_;
};

} // namespace experimental
Expand Down
14 changes: 7 additions & 7 deletions test/core/security/grpc_audit_logging_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -82,23 +82,23 @@ class AuditLoggingTest : public ::testing::Test {
} // namespace

TEST_F(AuditLoggingTest, SuccessfulLoggerCreation) {
auto result = AuditLoggerRegistry::ParseAuditLoggerConfig(kName, Json());
auto result = AuditLoggerRegistry::ParseConfig(kName, Json());
ASSERT_TRUE(result.ok());
ASSERT_NE(AuditLoggerRegistry::CreateAuditLogger(std::move(result.value())),
nullptr);
}

TEST_F(AuditLoggingTest, UnknownLogger) {
auto result =
AuditLoggerRegistry::ParseAuditLoggerConfig("unknown_logger", Json());
EXPECT_EQ(result.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_EQ(result.status().message(), "unsupported audit logger type")
auto result = AuditLoggerRegistry::ParseConfig("unknown_logger", Json());
EXPECT_EQ(result.status().code(), absl::StatusCode::kNotFound);
EXPECT_EQ(result.status().message(),
"audit logger factory for unknown_logger does not exist")
<< result.status();
}

TEST_F(AuditLoggingTest, AuditLoggerFactoryExistenceChecks) {
EXPECT_TRUE(AuditLoggerRegistry::AuditLoggerFactoryExists(kName));
EXPECT_FALSE(AuditLoggerRegistry::AuditLoggerFactoryExists("unknown_logger"));
EXPECT_TRUE(AuditLoggerRegistry::FactoryExists(kName));
EXPECT_FALSE(AuditLoggerRegistry::FactoryExists("unknown_logger"));
}

} // namespace testing
Expand Down