summaryrefslogtreecommitdiff
path: root/src/mongo/rpc/op_msg_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/rpc/op_msg_test.cpp')
-rw-r--r--src/mongo/rpc/op_msg_test.cpp144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/mongo/rpc/op_msg_test.cpp b/src/mongo/rpc/op_msg_test.cpp
index ead4dbe1977..ea07a42ea31 100644
--- a/src/mongo/rpc/op_msg_test.cpp
+++ b/src/mongo/rpc/op_msg_test.cpp
@@ -34,7 +34,15 @@
#include "mongo/base/static_assert.h"
#include "mongo/bson/json.h"
+#include "mongo/db/auth/authorization_manager_impl.h"
+#include "mongo/db/auth/authorization_session.h"
+#include "mongo/db/auth/authorization_session_impl.h"
+#include "mongo/db/auth/authz_manager_external_state_mock.h"
+#include "mongo/db/auth/security_token_gen.h"
+#include "mongo/db/auth/validated_tenancy_scope.h"
#include "mongo/db/jsobj.h"
+#include "mongo/db/multitenancy_gen.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/logv2/log.h"
#include "mongo/unittest/log_test.h"
#include "mongo/unittest/unittest.h"
@@ -44,6 +52,26 @@
namespace mongo {
+
+class AuthorizationSessionImplTestHelper {
+public:
+ /**
+ * Synthesize a user with the useTenant privilege and add them to the authorization session.
+ */
+ static void grantUseTenant(Client& client) {
+ User user(UserName("useTenant", "admin"));
+ user.setPrivileges(
+ {Privilege(ResourcePattern::forClusterResource(), ActionType::useTenant)});
+ auto* as = dynamic_cast<AuthorizationSessionImpl*>(AuthorizationSession::get(client));
+ if (as->_authenticatedUser != boost::none) {
+ as->logoutAllDatabases(&client, "AuthorizationSessionImplTestHelper"_sd);
+ }
+ as->_authenticatedUser = std::move(user);
+ as->_authenticationMode = AuthorizationSession::AuthenticationMode::kConnection;
+ as->_updateInternalAuthorizationState();
+ }
+};
+
namespace rpc {
namespace test {
namespace {
@@ -763,6 +791,122 @@ TEST(OpMsgSerializer, SetFlagWorks) {
}
}
+class OpMsgWithAuth : public mongo::ScopedGlobalServiceContextForTest, public unittest::Test {
+protected:
+ void setUp() final {
+ auto authzManagerState = std::make_unique<AuthzManagerExternalStateMock>();
+ auto authzManager = std::make_unique<AuthorizationManagerImpl>(
+ getServiceContext(), std::move(authzManagerState));
+ authzManager->setAuthEnabled(true);
+ AuthorizationManager::set(getServiceContext(), std::move(authzManager));
+
+ client = getServiceContext()->makeClient("test");
+ }
+
+ BSONObj makeSecurityToken(const UserName& userName) {
+ constexpr auto authUserFieldName = auth::SecurityToken::kAuthenticatedUserFieldName;
+ auto authUser = userName.toBSON(true /* serialize token */);
+ ASSERT_EQ(authUser["tenant"_sd].type(), jstOID);
+ using VTS = auth::ValidatedTenancyScope;
+ return VTS(BSON(authUserFieldName << authUser), VTS::TokenForTestingTag{})
+ .getOriginalToken();
+ }
+
+ ServiceContext::UniqueClient client;
+};
+
+TEST_F(OpMsgWithAuth, ParseValidatedTenancyScopeFromSecurityToken) {
+ gMultitenancySupport = true;
+
+ const auto kTenantId = TenantId(OID::gen());
+ const auto token = makeSecurityToken(UserName("user", "admin", kTenantId));
+ auto msg =
+ OpMsgBytes{
+ kNoFlags, //
+ kBodySection,
+ fromjson("{ping: 1}"),
+
+ kDocSequenceSection,
+ Sized{
+ "docs", //
+ fromjson("{a: 1}"),
+ fromjson("{a: 2}"),
+ },
+
+ kSecurityTokenSection,
+ token,
+ }
+ .parse(client.get());
+
+ auto body = BSON("ping" << 1);
+
+ ASSERT(msg.validatedTenancyScope);
+ ASSERT_EQ(msg.validatedTenancyScope->tenantId(), kTenantId);
+}
+
+TEST_F(OpMsgWithAuth, ParseValidatedTenancyScopeFromDollarTenant) {
+ gMultitenancySupport = true;
+ AuthorizationSessionImplTestHelper::grantUseTenant(*(client.get()));
+
+ const auto kTenantId = TenantId(OID::gen());
+ const auto body = BSON("ping" << 1 << "$tenant" << kTenantId);
+ auto msg =
+ OpMsgBytes{
+ kNoFlags, //
+ kBodySection,
+ body,
+
+ kDocSequenceSection,
+ Sized{
+ "docs", //
+ fromjson("{a: 1}"),
+ fromjson("{a: 2}"),
+ },
+ }
+ .parse(client.get());
+
+ ASSERT(msg.validatedTenancyScope);
+ ASSERT_EQ(msg.validatedTenancyScope->tenantId(), kTenantId);
+}
+
+TEST_F(OpMsgWithAuth, ValidatedTenancyScopeShouldNotBeSerialized) {
+ gMultitenancySupport = true;
+ AuthorizationSessionImplTestHelper::grantUseTenant(*(client.get()));
+
+ const auto kTenantId = TenantId(OID::gen());
+ const auto body = BSON("ping" << 1 << "$tenant" << kTenantId);
+ auto msgBytes = OpMsgBytes{
+ kNoFlags, //
+ kBodySection,
+ body,
+
+ kDocSequenceSection,
+ Sized{
+ "docs", //
+ fromjson("{a: 1}"),
+ fromjson("{a: 2}"),
+ },
+ };
+ auto msg = msgBytes.parse(client.get());
+ ASSERT(msg.validatedTenancyScope);
+
+ auto serializedMsg = msg.serialize();
+ testSerializer(serializedMsg,
+ OpMsgBytes{
+ kNoFlags, //
+
+ kDocSequenceSection,
+ Sized{
+ "docs", //
+ fromjson("{a: 1}"),
+ fromjson("{a: 2}"),
+ },
+
+ kBodySection,
+ body,
+ });
+}
+
TEST(OpMsgRequest, GetDatabaseWorks) {
OpMsgRequest msg;
msg.body = fromjson("{$db: 'foo'}");