diff options
author | Sara Golemon <sara.golemon@mongodb.com> | 2020-10-27 16:21:08 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-11-10 14:26:10 +0000 |
commit | bb84b6a1d1d18eed4f05fdb910adc59644b683eb (patch) | |
tree | 7203f005399939bb8de83fa7ab942bfdea59c22f /src/mongo/db | |
parent | 4e4ebb8fef276c28011aebecf8a0ed12e69a9f9b (diff) | |
download | mongo-bb84b6a1d1d18eed4f05fdb910adc59644b683eb.tar.gz |
SERVER-51865 IDLify user cache commands
Diffstat (limited to 'src/mongo/db')
4 files changed, 73 insertions, 95 deletions
diff --git a/src/mongo/db/commands/user_management_commands.cpp b/src/mongo/db/commands/user_management_commands.cpp index 44edd0d4fd8..b0d55c65396 100644 --- a/src/mongo/db/commands/user_management_commands.cpp +++ b/src/mongo/db/commands/user_management_commands.cpp @@ -908,16 +908,25 @@ private: // Used by most UMC commands. struct UMCStdParams { + static constexpr bool adminOnly = false; static constexpr bool supportsWriteConcern = true; static constexpr auto allowedOnSecondary = BasicCommand::AllowedOnSecondary::kNever; }; // Used by {usersInfo:...} and {rolesInfo:...} struct UMCInfoParams { + static constexpr bool adminOnly = false; static constexpr bool supportsWriteConcern = false; static constexpr auto allowedOnSecondary = BasicCommand::AllowedOnSecondary::kOptIn; }; +// Used by {invalidateUserCache:...} and {_getUserCacheGeneration:...} +struct UMCCacheParams { + static constexpr bool adminOnly = true; + static constexpr bool supportsWriteConcern = false; + static constexpr auto allowedOnSecondary = BasicCommand::AllowedOnSecondary::kAlways; +}; + template <typename RequestT, typename ReplyT, typename Params = UMCStdParams> class CmdUMCTyped : public TypedCommand<CmdUMCTyped<RequestT, ReplyT, Params>> { public: @@ -941,11 +950,15 @@ public: auth::checkAuthForTypedCommand(opCtx->getClient(), request()); } - NamespaceString ns() const override { + NamespaceString ns() const final { return NamespaceString(request().getDbName(), ""); } }; + bool adminOnly() const final { + return Params::adminOnly; + } + typename TC::AllowedOnSecondary secondaryAllowed(ServiceContext*) const final { return Params::allowedOnSecondary; } @@ -1943,83 +1956,30 @@ RolesInfoReply CmdUMCTyped<RolesInfoCommand, RolesInfoReply, UMCInfoParams>::Inv return reply; } -class CmdInvalidateUserCache : public BasicCommand { -public: - CmdInvalidateUserCache() : BasicCommand("invalidateUserCache") {} - - AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { - return AllowedOnSecondary::kAlways; - } - - bool adminOnly() const override { - return true; - } - - bool supportsWriteConcern(const BSONObj& cmd) const override { - return false; - } - - std::string help() const override { - return "Invalidates the in-memory cache of user information"; - } - - Status checkAuthForCommand(Client* client, - const std::string& dbname, - const BSONObj& cmdObj) const override { - return auth::checkAuthForInvalidateUserCacheCommand(client); - } - - bool run(OperationContext* opCtx, - const std::string& dbname, - const BSONObj& cmdObj, - BSONObjBuilder& result) override { - AuthorizationManager* authzManager = AuthorizationManager::get(opCtx->getServiceContext()); - auto lk = requireReadableAuthSchema26Upgrade(opCtx, authzManager); - authzManager->invalidateUserCache(opCtx); - return true; - } - -} cmdInvalidateUserCache; - -class CmdGetCacheGeneration : public BasicCommand { -public: - CmdGetCacheGeneration() : BasicCommand("_getUserCacheGeneration") {} - - AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { - return AllowedOnSecondary::kAlways; - } - - bool adminOnly() const override { - return true; - } - - bool supportsWriteConcern(const BSONObj& cmd) const override { - return false; - } - - std::string help() const override { - return "internal"; - } - - Status checkAuthForCommand(Client* client, - const std::string& dbname, - const BSONObj& cmdObj) const override { - return auth::checkAuthForGetUserCacheGenerationCommand(client); - } - - bool run(OperationContext* opCtx, - const std::string& dbname, - const BSONObj& cmdObj, - BSONObjBuilder& result) override { - uassert(ErrorCodes::IllegalOperation, - "_getUserCacheGeneration can only be run on config servers", - serverGlobalParams.clusterRole == ClusterRole::ConfigServer); - AuthorizationManager* authzManager = AuthorizationManager::get(opCtx->getServiceContext()); - result.append("cacheGeneration", authzManager->getCacheGeneration()); - return true; - } +CmdUMCTyped<InvalidateUserCacheCommand, void, UMCCacheParams> cmdInvalidateUserCache; +template <> +void CmdUMCTyped<InvalidateUserCacheCommand, void, UMCCacheParams>::Invocation::typedRun( + OperationContext* opCtx) { + auto* authzManager = AuthorizationManager::get(opCtx->getServiceContext()); + auto lk = requireReadableAuthSchema26Upgrade(opCtx, authzManager); + authzManager->invalidateUserCache(opCtx); +} -} cmdGetCacheGeneration; +CmdUMCTyped<GetUserCacheGenerationCommand, GetUserCacheGenerationReply, UMCCacheParams> + cmdGetUserCacheGeneration; +template <> +GetUserCacheGenerationReply +CmdUMCTyped<GetUserCacheGenerationCommand, GetUserCacheGenerationReply, UMCCacheParams>:: + Invocation::typedRun(OperationContext* opCtx) { + uassert(ErrorCodes::IllegalOperation, + "_getUserCacheGeneration can only be run on config servers", + serverGlobalParams.clusterRole == ClusterRole::ConfigServer); + + GetUserCacheGenerationReply reply; + auto* authzManager = AuthorizationManager::get(opCtx->getServiceContext()); + reply.setCacheGeneration(authzManager->getCacheGeneration()); + return reply; +} /** * This command is used only by mongorestore to handle restoring users/roles. We do this so diff --git a/src/mongo/db/commands/user_management_commands.idl b/src/mongo/db/commands/user_management_commands.idl index 0dfbdd9fb17..8897b8b7da1 100644 --- a/src/mongo/db/commands/user_management_commands.idl +++ b/src/mongo/db/commands/user_management_commands.idl @@ -82,6 +82,14 @@ structs: type: object_owned optional: true + GetUserCacheGenerationReply: + description: "Reply from _getUserCacheGeneration command" + strict: false + fields: + cacheGeneration: + description: "Cache generation" + type: objectid + UMCTransactionFailPoint: description: Data for umcTransaction failpoint fields: @@ -375,3 +383,17 @@ commands: If viewing all users, you cannot specify this field. type: safeBool default: false + + invalidateUserCache: + description: "Invalidate the user cache" + namespace: ignored + command_name: invalidateUserCache + cpp_name: InvalidateUserCacheCommand + strict: true + + _getUserCacheGeneration: + description: "Returns the current user cache generation" + namespace: ignored + command_name: _getUserCacheGeneration + cpp_name: GetUserCacheGenerationCommand + strict: true diff --git a/src/mongo/db/commands/user_management_commands_common.cpp b/src/mongo/db/commands/user_management_commands_common.cpp index 06c4f2683ea..d352949342d 100644 --- a/src/mongo/db/commands/user_management_commands_common.cpp +++ b/src/mongo/db/commands/user_management_commands_common.cpp @@ -346,22 +346,20 @@ void checkAuthForTypedCommand(Client* client, const RolesInfoCommand& request) { } } -Status checkAuthForInvalidateUserCacheCommand(Client* client) { - AuthorizationSession* authzSession = AuthorizationSession::get(client); - if (!authzSession->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(), - ActionType::invalidateUserCache)) { - return Status(ErrorCodes::Unauthorized, "Not authorized to invalidate user cache"); - } - return Status::OK(); +void checkAuthForTypedCommand(Client* client, const InvalidateUserCacheCommand& request) { + auto* as = AuthorizationSession::get(client); + uassert(ErrorCodes::Unauthorized, + "Not authorized to invalidate user cache", + as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(), + ActionType::invalidateUserCache)); } -Status checkAuthForGetUserCacheGenerationCommand(Client* client) { - AuthorizationSession* authzSession = AuthorizationSession::get(client); - if (!authzSession->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(), - ActionType::internal)) { - return Status(ErrorCodes::Unauthorized, "Not authorized to get cache generation"); - } - return Status::OK(); +void checkAuthForTypedCommand(Client* client, const GetUserCacheGenerationCommand& request) { + auto* as = AuthorizationSession::get(client); + uassert(ErrorCodes::Unauthorized, + "Not authorized to get cache generation", + as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(), + ActionType::internal)); } Status checkAuthForMergeAuthzCollectionsCommand(Client* client, const BSONObj& cmdObj) { diff --git a/src/mongo/db/commands/user_management_commands_common.h b/src/mongo/db/commands/user_management_commands_common.h index 3e162039d9f..1af4316c899 100644 --- a/src/mongo/db/commands/user_management_commands_common.h +++ b/src/mongo/db/commands/user_management_commands_common.h @@ -95,10 +95,8 @@ void checkAuthForTypedCommand(Client*, const RevokePrivilegesFromRoleCommand&); void checkAuthForTypedCommand(Client*, const DropAllRolesFromDatabaseCommand&); void checkAuthForTypedCommand(Client*, const UsersInfoCommand&); void checkAuthForTypedCommand(Client*, const RolesInfoCommand&); - -Status checkAuthForInvalidateUserCacheCommand(Client* client); - -Status checkAuthForGetUserCacheGenerationCommand(Client* client); +void checkAuthForTypedCommand(Client*, const InvalidateUserCacheCommand&); +void checkAuthForTypedCommand(Client*, const GetUserCacheGenerationCommand&); Status checkAuthForMergeAuthzCollectionsCommand(Client* client, const BSONObj& cmdObj); |