summaryrefslogtreecommitdiff
path: root/src/mongo/db/auth
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/auth')
-rw-r--r--src/mongo/db/auth/action_set.cpp11
-rw-r--r--src/mongo/db/auth/action_set.h4
-rw-r--r--src/mongo/db/auth/privilege_parser.cpp36
-rw-r--r--src/mongo/db/auth/privilege_parser.h12
-rw-r--r--src/mongo/db/auth/privilege_parser_test.cpp68
-rw-r--r--src/mongo/db/auth/resource_pattern.h37
-rw-r--r--src/mongo/db/auth/user_management_commands_parser.cpp2
7 files changed, 157 insertions, 13 deletions
diff --git a/src/mongo/db/auth/action_set.cpp b/src/mongo/db/auth/action_set.cpp
index b7c17ae1996..e1f38a7746b 100644
--- a/src/mongo/db/auth/action_set.cpp
+++ b/src/mongo/db/auth/action_set.cpp
@@ -94,4 +94,15 @@ namespace mongo {
return str.str();
}
+ std::vector<std::string> ActionSet::getActionsAsStrings() const {
+ std::vector<std::string> result;
+ for (int i = 0; i < ActionType::actionTypeEndValue; i++) {
+ ActionType action(i);
+ if (contains(action)) {
+ result.push_back(ActionType::actionToString(action));
+ }
+ }
+ return result;
+ }
+
} // namespace mongo
diff --git a/src/mongo/db/auth/action_set.h b/src/mongo/db/auth/action_set.h
index 09cb1128341..ea1cab59017 100644
--- a/src/mongo/db/auth/action_set.h
+++ b/src/mongo/db/auth/action_set.h
@@ -16,6 +16,7 @@
#pragma once
#include <bitset>
+#include <vector>
#include "mongo/base/status.h"
#include "mongo/db/auth/action_type.h"
@@ -52,6 +53,9 @@ namespace mongo {
// Returns the string representation of this ActionSet
std::string toString() const;
+ // Returns a vector of strings representing the actions in the ActionSet.
+ std::vector<std::string> getActionsAsStrings() const;
+
// Takes a comma-separated string of action type string representations and returns
// an int bitmask of the actions.
static Status parseActionSetFromString(const std::string& actionsString, ActionSet* result);
diff --git a/src/mongo/db/auth/privilege_parser.cpp b/src/mongo/db/auth/privilege_parser.cpp
index 7cdcb92f0aa..e7d1def99df 100644
--- a/src/mongo/db/auth/privilege_parser.cpp
+++ b/src/mongo/db/auth/privilege_parser.cpp
@@ -333,9 +333,9 @@ namespace mongo {
return _resource;
}
- bool ParsedPrivilege::buildPrivilege(const ParsedPrivilege& parsedPrivilege,
- Privilege* result,
- std::string* errmsg) {
+ bool ParsedPrivilege::parsedPrivilegeToPrivilege(const ParsedPrivilege& parsedPrivilege,
+ Privilege* result,
+ std::string* errmsg) {
if (!parsedPrivilege.isValid(errmsg)) {
return false;
}
@@ -380,4 +380,34 @@ namespace mongo {
*result = Privilege(resource, actions);
return true;
}
+
+ bool ParsedPrivilege::privilegeToParsedPrivilege(const Privilege& privilege,
+ ParsedPrivilege* result,
+ std::string* errmsg) {
+ ParsedResource parsedResource;
+ if (privilege.getResourcePattern().isExactNamespacePattern()) {
+ parsedResource.setDb(privilege.getResourcePattern().databaseToMatch());
+ parsedResource.setCollection(privilege.getResourcePattern().collectionToMatch());
+ } else if (privilege.getResourcePattern().isDatabasePattern()) {
+ parsedResource.setDb(privilege.getResourcePattern().databaseToMatch());
+ parsedResource.setCollection("");
+ } else if (privilege.getResourcePattern().isCollectionPattern()) {
+ parsedResource.setDb("");
+ parsedResource.setCollection(privilege.getResourcePattern().collectionToMatch());
+ } else if (privilege.getResourcePattern().isAnyNormalResourcePattern()) {
+ parsedResource.setDb("");
+ parsedResource.setCollection("");
+ } else if (privilege.getResourcePattern().isClusterResourcePattern()) {
+ parsedResource.setCluster(true);
+ } else {
+ *errmsg = stream() << privilege.getResourcePattern().toString() <<
+ " is not a valid user-grantable resource pattern";
+ return false;
+ }
+
+ result->clear();
+ result->setResource(parsedResource);
+ result->setActions(privilege.getActions().getActionsAsStrings());
+ return result->isValid(errmsg);
+ }
} // namespace mongo
diff --git a/src/mongo/db/auth/privilege_parser.h b/src/mongo/db/auth/privilege_parser.h
index 4e28fec8493..235f6db12eb 100644
--- a/src/mongo/db/auth/privilege_parser.h
+++ b/src/mongo/db/auth/privilege_parser.h
@@ -122,9 +122,15 @@ namespace mongo {
/**
* Takes a parsedPrivilege and turns it into a true Privilege object.
*/
- static bool buildPrivilege(const ParsedPrivilege& parsedPrivilege,
- Privilege* result,
- std::string* errmsg);
+ static bool parsedPrivilegeToPrivilege(const ParsedPrivilege& parsedPrivilege,
+ Privilege* result,
+ std::string* errmsg);
+ /**
+ * Takes a Privilege object and turns it into a ParsedPrivilege.
+ */
+ static bool privilegeToParsedPrivilege(const Privilege& privilege,
+ ParsedPrivilege* result,
+ std::string* errmsg);
/** Copies all the fields present in 'this' to 'other'. */
void cloneTo(ParsedPrivilege* other) const;
diff --git a/src/mongo/db/auth/privilege_parser_test.cpp b/src/mongo/db/auth/privilege_parser_test.cpp
index 856772e3889..6f91f03cf66 100644
--- a/src/mongo/db/auth/privilege_parser_test.cpp
+++ b/src/mongo/db/auth/privilege_parser_test.cpp
@@ -97,64 +97,120 @@ namespace {
ASSERT(parsedPrivilege.isValid(&errmsg));
}
- TEST(PrivilegeParserTest, BuildPrivilegeTest) {
+ TEST(PrivilegeParserTest, ConvertBetweenPrivilegeTest) {
ParsedPrivilege parsedPrivilege;
Privilege privilege;
std::string errmsg;
+ std::vector<std::string> actionsVector;
+ actionsVector.push_back("find");
// Works with wildcard db and resource
parsedPrivilege.parseBSON(BSON("resource" << BSON("db" << "" << "collection" << "") <<
"actions" << BSON_ARRAY("find")),
&errmsg);
ASSERT(parsedPrivilege.isValid(&errmsg));
- ASSERT(ParsedPrivilege::buildPrivilege(parsedPrivilege, &privilege, &errmsg));
+ ASSERT(ParsedPrivilege::parsedPrivilegeToPrivilege(parsedPrivilege, &privilege, &errmsg));
ASSERT(privilege.getActions().contains(ActionType::find));
ASSERT(!privilege.getActions().contains(ActionType::insert));
ASSERT_EQUALS(privilege.getResourcePattern(), ResourcePattern::forAnyNormalResource());
+ ASSERT(ParsedPrivilege::privilegeToParsedPrivilege(privilege, &parsedPrivilege, &errmsg));
+ ASSERT(parsedPrivilege.isValid(&errmsg));
+ ASSERT(parsedPrivilege.isResourceSet());
+ ASSERT_FALSE(parsedPrivilege.getResource().isClusterSet());
+ ASSERT(parsedPrivilege.getResource().isDbSet());
+ ASSERT(parsedPrivilege.getResource().isCollectionSet());
+ ASSERT_EQUALS("", parsedPrivilege.getResource().getDb());
+ ASSERT_EQUALS("", parsedPrivilege.getResource().getCollection());
+ ASSERT(parsedPrivilege.isActionsSet());
+ ASSERT(actionsVector == parsedPrivilege.getActions());
+
// Works with exact namespaces
parsedPrivilege.parseBSON(BSON("resource" << BSON("db" << "test" <<
"collection" << "foo") <<
"actions" << BSON_ARRAY("find")),
&errmsg);
ASSERT(parsedPrivilege.isValid(&errmsg));
- ASSERT(ParsedPrivilege::buildPrivilege(parsedPrivilege, &privilege, &errmsg));
+ ASSERT(ParsedPrivilege::parsedPrivilegeToPrivilege(parsedPrivilege, &privilege, &errmsg));
ASSERT(privilege.getActions().contains(ActionType::find));
ASSERT(!privilege.getActions().contains(ActionType::insert));
ASSERT_EQUALS(privilege.getResourcePattern(),
ResourcePattern::forExactNamespace(NamespaceString("test.foo")));
+ ASSERT(ParsedPrivilege::privilegeToParsedPrivilege(privilege, &parsedPrivilege, &errmsg));
+ ASSERT(parsedPrivilege.isValid(&errmsg));
+ ASSERT(parsedPrivilege.isResourceSet());
+ ASSERT_FALSE(parsedPrivilege.getResource().isClusterSet());
+ ASSERT(parsedPrivilege.getResource().isDbSet());
+ ASSERT(parsedPrivilege.getResource().isCollectionSet());
+ ASSERT_EQUALS("test", parsedPrivilege.getResource().getDb());
+ ASSERT_EQUALS("foo", parsedPrivilege.getResource().getCollection());
+ ASSERT(parsedPrivilege.isActionsSet());
+ ASSERT(actionsVector == parsedPrivilege.getActions());
+
// Works with database resource
parsedPrivilege.parseBSON(BSON("resource" << BSON("db" << "test" <<
"collection" << "") <<
"actions" << BSON_ARRAY("find")),
&errmsg);
ASSERT(parsedPrivilege.isValid(&errmsg));
- ASSERT(ParsedPrivilege::buildPrivilege(parsedPrivilege, &privilege, &errmsg));
+ ASSERT(ParsedPrivilege::parsedPrivilegeToPrivilege(parsedPrivilege, &privilege, &errmsg));
ASSERT(privilege.getActions().contains(ActionType::find));
ASSERT(!privilege.getActions().contains(ActionType::insert));
ASSERT_EQUALS(privilege.getResourcePattern(), ResourcePattern::forDatabaseName("test"));
+ ASSERT(ParsedPrivilege::privilegeToParsedPrivilege(privilege, &parsedPrivilege, &errmsg));
+ ASSERT(parsedPrivilege.isValid(&errmsg));
+ ASSERT(parsedPrivilege.isResourceSet());
+ ASSERT_FALSE(parsedPrivilege.getResource().isClusterSet());
+ ASSERT(parsedPrivilege.getResource().isDbSet());
+ ASSERT(parsedPrivilege.getResource().isCollectionSet());
+ ASSERT_EQUALS("test", parsedPrivilege.getResource().getDb());
+ ASSERT_EQUALS("", parsedPrivilege.getResource().getCollection());
+ ASSERT(parsedPrivilege.isActionsSet());
+ ASSERT(actionsVector == parsedPrivilege.getActions());
+
// Works with collection resource
parsedPrivilege.parseBSON(BSON("resource" << BSON("db" << "" <<
"collection" << "foo") <<
"actions" << BSON_ARRAY("find")),
&errmsg);
ASSERT(parsedPrivilege.isValid(&errmsg));
- ASSERT(ParsedPrivilege::buildPrivilege(parsedPrivilege, &privilege, &errmsg));
+ ASSERT(ParsedPrivilege::parsedPrivilegeToPrivilege(parsedPrivilege, &privilege, &errmsg));
ASSERT(privilege.getActions().contains(ActionType::find));
ASSERT(!privilege.getActions().contains(ActionType::insert));
ASSERT_EQUALS(privilege.getResourcePattern(), ResourcePattern::forCollectionName("foo"));
+ ASSERT(ParsedPrivilege::privilegeToParsedPrivilege(privilege, &parsedPrivilege, &errmsg));
+ ASSERT(parsedPrivilege.isValid(&errmsg));
+ ASSERT(parsedPrivilege.isResourceSet());
+ ASSERT_FALSE(parsedPrivilege.getResource().isClusterSet());
+ ASSERT(parsedPrivilege.getResource().isDbSet());
+ ASSERT(parsedPrivilege.getResource().isCollectionSet());
+ ASSERT_EQUALS("", parsedPrivilege.getResource().getDb());
+ ASSERT_EQUALS("foo", parsedPrivilege.getResource().getCollection());
+ ASSERT(parsedPrivilege.isActionsSet());
+ ASSERT(actionsVector == parsedPrivilege.getActions());
+
// Works with cluster resource
parsedPrivilege.parseBSON(BSON("resource" << BSON("cluster" << true) <<
"actions" << BSON_ARRAY("find")),
&errmsg);
ASSERT(parsedPrivilege.isValid(&errmsg));
- ASSERT(ParsedPrivilege::buildPrivilege(parsedPrivilege, &privilege, &errmsg));
+ ASSERT(ParsedPrivilege::parsedPrivilegeToPrivilege(parsedPrivilege, &privilege, &errmsg));
ASSERT(privilege.getActions().contains(ActionType::find));
ASSERT(!privilege.getActions().contains(ActionType::insert));
ASSERT_EQUALS(privilege.getResourcePattern(), ResourcePattern::forClusterResource());
+
+ ASSERT(ParsedPrivilege::privilegeToParsedPrivilege(privilege, &parsedPrivilege, &errmsg));
+ ASSERT(parsedPrivilege.isValid(&errmsg));
+ ASSERT(parsedPrivilege.isResourceSet());
+ ASSERT(parsedPrivilege.getResource().isClusterSet());
+ ASSERT(parsedPrivilege.getResource().getCluster());
+ ASSERT_FALSE(parsedPrivilege.getResource().isDbSet());
+ ASSERT_FALSE(parsedPrivilege.getResource().isCollectionSet());
+ ASSERT(parsedPrivilege.isActionsSet());
+ ASSERT(actionsVector == parsedPrivilege.getActions());
}
} // namespace
diff --git a/src/mongo/db/auth/resource_pattern.h b/src/mongo/db/auth/resource_pattern.h
index ba04e382e00..24bc1020301 100644
--- a/src/mongo/db/auth/resource_pattern.h
+++ b/src/mongo/db/auth/resource_pattern.h
@@ -98,6 +98,27 @@ namespace mongo {
}
/**
+ * Returns true if this pattern matches on the collection name only.
+ */
+ bool isCollectionPattern() const {
+ return _matchType == matchCollectionName;
+ }
+
+ /**
+ * Returns true if this pattern matches the cluster resource only.
+ */
+ bool isClusterResourcePattern() const {
+ return _matchType == matchClusterResource;
+ }
+
+ /**
+ * Returns true if this pattern matches only any normal resource.
+ */
+ bool isAnyNormalResourcePattern() const {
+ return _matchType == matchAnyNormalResource;
+ }
+
+ /**
* Returns true if this pattern matches nothing at all.
*/
bool matchesNothing() const { return matchNever == _matchType; }
@@ -155,6 +176,22 @@ namespace mongo {
*/
const NamespaceString& ns() const { return _ns; }
+ /**
+ * Returns the database that this pattern matches.
+ *
+ * Behavior is undefined unless the pattern is of type matchDatabaseName or
+ * matchExactNamespace
+ */
+ StringData databaseToMatch() const { return _ns.db(); }
+
+ /**
+ * Returns the collection that this pattern matches.
+ *
+ * Behavior is undefined unless the pattern is of type matchCollectionName or
+ * matchExactNamespace
+ */
+ StringData collectionToMatch() const { return _ns.coll(); }
+
std::string toString() const;
inline size_t hash() const {
diff --git a/src/mongo/db/auth/user_management_commands_parser.cpp b/src/mongo/db/auth/user_management_commands_parser.cpp
index 3fe5f107621..7f7c1fe04d4 100644
--- a/src/mongo/db/auth/user_management_commands_parser.cpp
+++ b/src/mongo/db/auth/user_management_commands_parser.cpp
@@ -553,7 +553,7 @@ namespace auth {
}
Privilege privilege;
- if (!ParsedPrivilege::buildPrivilege(parsedPrivilege, &privilege, &errmsg)) {
+ if (!ParsedPrivilege::parsedPrivilegeToPrivilege(parsedPrivilege, &privilege, &errmsg)) {
return Status(ErrorCodes::FailedToParse, errmsg);
}