diff options
author | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2018-02-04 09:01:03 -0500 |
---|---|---|
committer | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2018-02-14 17:12:44 -0500 |
commit | e5e8dde676b585f5620608e95e93b9da295890c5 (patch) | |
tree | 15682c345e91499c4a4818214e881d3ffab00d08 /src/mongo/db/commands/distinct.cpp | |
parent | 4d18e6908acc852c77e97df0bf169c442a9bb306 (diff) | |
download | mongo-e5e8dde676b585f5620608e95e93b9da295890c5.tar.gz |
SERVER-32367 Clean up the AutoGet* suite of classes
* Get rid of AutoGetCollectionOrViewForReadCommand
* Get rid of constructors accepting Lock::DBLock
* Always check for shard version, unless the namespace represents a view
Diffstat (limited to 'src/mongo/db/commands/distinct.cpp')
-rw-r--r-- | src/mongo/db/commands/distinct.cpp | 63 |
1 files changed, 39 insertions, 24 deletions
diff --git a/src/mongo/db/commands/distinct.cpp b/src/mongo/db/commands/distinct.cpp index 584f9b7c979..eba4fdd51bc 100644 --- a/src/mongo/db/commands/distinct.cpp +++ b/src/mongo/db/commands/distinct.cpp @@ -35,13 +35,8 @@ #include <string> #include <vector> -#include "mongo/bson/util/bson_extract.h" -#include "mongo/db/auth/action_set.h" -#include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/privilege.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/bson/dotted_path_support.h" -#include "mongo/db/catalog/collection.h" -#include "mongo/db/catalog/database.h" #include "mongo/db/client.h" #include "mongo/db/clientcursor.h" #include "mongo/db/commands.h" @@ -98,12 +93,20 @@ public: return FindCommon::kInitReplyBufferSize; } - void addRequiredPrivileges(const std::string& dbname, - const BSONObj& cmdObj, - std::vector<Privilege>* out) const override { - ActionSet actions; - actions.addAction(ActionType::find); - out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions)); + Status checkAuthForOperation(OperationContext* opCtx, + const std::string& dbname, + const BSONObj& cmdObj) const override { + AuthorizationSession* authSession = AuthorizationSession::get(opCtx->getClient()); + + if (!authSession->isAuthorizedToParseNamespaceElement(cmdObj.firstElement())) { + return Status(ErrorCodes::Unauthorized, "Unauthorized"); + } + + const auto hasTerm = false; + return authSession->checkAuthForFind( + AutoGetCollection::resolveNamespaceStringOrUUID( + opCtx, CommandHelpers::parseNsOrUUID(dbname, cmdObj)), + hasTerm); } Status explain(OperationContext* opCtx, @@ -111,17 +114,21 @@ public: const BSONObj& cmdObj, ExplainOptions::Verbosity verbosity, BSONObjBuilder* out) const override { - const NamespaceString nss(CommandHelpers::parseNsCollectionRequired(dbname, cmdObj)); + // Acquire locks and resolve possible UUID. The RAII object is optional, because in the case + // of a view, the locks need to be released. + boost::optional<AutoGetCollectionForReadCommand> ctx; + ctx.emplace(opCtx, + CommandHelpers::parseNsOrUUID(dbname, cmdObj), + AutoGetCollection::ViewMode::kViewsPermitted); + const auto nss = ctx->getNss(); const ExtensionsCallbackReal extensionsCallback(opCtx, &nss); auto parsedDistinct = uassertStatusOK(ParsedDistinct::parse(opCtx, nss, cmdObj, extensionsCallback, true)); - AutoGetCollectionOrViewForReadCommand ctx(opCtx, nss); - Collection* collection = ctx.getCollection(); - - if (ctx.getView()) { - ctx.releaseLocksForView(); + if (ctx->getView()) { + // Relinquish locks. The aggregation command will re-acquire them. + ctx.reset(); auto viewAggregation = parsedDistinct.asAggregationCommand(); if (!viewAggregation.isOK()) { @@ -138,6 +145,8 @@ public: opCtx, nss, viewAggRequest.getValue(), viewAggregation.getValue(), *out); } + Collection* const collection = ctx->getCollection(); + auto executor = uassertStatusOK(getExecutorDistinct( opCtx, collection, nss.ns(), &parsedDistinct, PlanExecutor::YIELD_AUTO)); @@ -149,17 +158,21 @@ public: const std::string& dbname, const BSONObj& cmdObj, BSONObjBuilder& result) override { - const NamespaceString nss(CommandHelpers::parseNsCollectionRequired(dbname, cmdObj)); + // Acquire locks and resolve possible UUID. The RAII object is optional, because in the case + // of a view, the locks need to be released. + boost::optional<AutoGetCollectionForReadCommand> ctx; + ctx.emplace(opCtx, + CommandHelpers::parseNsOrUUID(dbname, cmdObj), + AutoGetCollection::ViewMode::kViewsPermitted); + const auto& nss = ctx->getNss(); const ExtensionsCallbackReal extensionsCallback(opCtx, &nss); auto parsedDistinct = uassertStatusOK(ParsedDistinct::parse(opCtx, nss, cmdObj, extensionsCallback, false)); - AutoGetCollectionOrViewForReadCommand ctx(opCtx, nss); - Collection* collection = ctx.getCollection(); - - if (ctx.getView()) { - ctx.releaseLocksForView(); + if (ctx->getView()) { + // Relinquish locks. The aggregation command will re-acquire them. + ctx.reset(); auto viewAggregation = parsedDistinct.asAggregationCommand(); if (!viewAggregation.isOK()) { @@ -172,6 +185,8 @@ public: return true; } + Collection* const collection = ctx->getCollection(); + auto executor = getExecutorDistinct( opCtx, collection, nss.ns(), &parsedDistinct, PlanExecutor::YIELD_AUTO); if (!executor.isOK()) { |