diff options
author | Spencer T Brody <spencer@10gen.com> | 2012-11-06 17:56:00 -0500 |
---|---|---|
committer | Spencer T Brody <spencer@10gen.com> | 2012-11-07 17:04:39 -0500 |
commit | 288ef9cb3b6ae41afc97ba74e4cf6d15e7a1c194 (patch) | |
tree | df94221bf8f08780d694dcbfacd46232dca4f491 /src/mongo/db/auth | |
parent | bfbc29331726fdd2663bdcb6eeae44dce2bed200 (diff) | |
download | mongo-288ef9cb3b6ae41afc97ba74e4cf6d15e7a1c194.tar.gz |
Rename Capability to Privilege. SERVER-7126
Diffstat (limited to 'src/mongo/db/auth')
-rw-r--r-- | src/mongo/db/auth/SConscript | 8 | ||||
-rw-r--r-- | src/mongo/db/auth/acquired_privilege.h (renamed from src/mongo/db/auth/acquired_capability.h) | 14 | ||||
-rw-r--r-- | src/mongo/db/auth/action_set.h | 4 | ||||
-rw-r--r-- | src/mongo/db/auth/authorization_manager.cpp | 56 | ||||
-rw-r--r-- | src/mongo/db/auth/authorization_manager.h | 43 | ||||
-rw-r--r-- | src/mongo/db/auth/authorization_manager_test.cpp | 70 | ||||
-rw-r--r-- | src/mongo/db/auth/capability_set.cpp | 63 | ||||
-rw-r--r-- | src/mongo/db/auth/capability_set.h | 70 | ||||
-rw-r--r-- | src/mongo/db/auth/capability_set_test.cpp | 99 | ||||
-rwxr-xr-x | src/mongo/db/auth/generate_action_types.py | 2 | ||||
-rw-r--r-- | src/mongo/db/auth/privilege.cpp (renamed from src/mongo/db/auth/capability.cpp) | 9 | ||||
-rw-r--r-- | src/mongo/db/auth/privilege.h (renamed from src/mongo/db/auth/capability.h) | 10 | ||||
-rw-r--r-- | src/mongo/db/auth/privilege_set.cpp | 63 | ||||
-rw-r--r-- | src/mongo/db/auth/privilege_set.h | 70 | ||||
-rw-r--r-- | src/mongo/db/auth/privilege_set_test.cpp | 99 |
15 files changed, 340 insertions, 340 deletions
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript index aaf670bb956..d459a1b7202 100644 --- a/src/mongo/db/auth/SConscript +++ b/src/mongo/db/auth/SConscript @@ -11,16 +11,16 @@ env.Command(['action_type.h', 'action_type.cpp'], ['generate_action_types.py', ' env.StaticLibrary('authcore', ['action_set.cpp', 'action_type.cpp', 'authorization_manager.cpp', - 'capability.cpp', - 'capability_set.cpp', 'principal.cpp', - 'principal_set.cpp'], + 'principal_set.cpp', + 'privilege.cpp', + 'privilege_set.cpp'], LIBDEPS=['$BUILD_DIR/mongo/base/base', '$BUILD_DIR/mongo/stringutils']) env.StaticLibrary('auth', ['external_state.cpp'], LIBDEPS=['authcore']) env.CppUnitTest('action_set_test', 'action_set_test.cpp', LIBDEPS=['authcore']) -env.CppUnitTest('capability_set_test', 'capability_set_test.cpp', LIBDEPS=['authcore']) env.CppUnitTest('principal_set_test', 'principal_set_test.cpp', LIBDEPS=['authcore']) +env.CppUnitTest('privilege_set_test', 'privilege_set_test.cpp', LIBDEPS=['authcore']) env.CppUnitTest('authorization_manager_test', 'authorization_manager_test.cpp', LIBDEPS=['authcore']) diff --git a/src/mongo/db/auth/acquired_capability.h b/src/mongo/db/auth/acquired_privilege.h index 080d55bce12..cc622de01bd 100644 --- a/src/mongo/db/auth/acquired_capability.h +++ b/src/mongo/db/auth/acquired_privilege.h @@ -16,8 +16,8 @@ #pragma once -#include "mongo/db/auth/capability.h" #include "mongo/db/auth/principal.h" +#include "mongo/db/auth/privilege.h" namespace mongo { @@ -25,20 +25,20 @@ namespace mongo { * A representation that a given principal has the permission to perform a set of actions on a * specific resource. */ - class AcquiredCapability { + class AcquiredPrivilege { public: - AcquiredCapability(const Capability& capability, Principal* principal) : - _capability(capability), _principal(principal) {} - ~AcquiredCapability() {} + AcquiredPrivilege(const Privilege& privilege, Principal* principal) : + _privilege(privilege), _principal(principal) {} + ~AcquiredPrivilege() {} const Principal* getPrincipal() const { return _principal; } - const Capability& getCapability() const { return _capability; } + const Privilege& getPrivilege() const { return _privilege; } private: - Capability _capability; + Privilege _privilege; Principal* _principal; }; diff --git a/src/mongo/db/auth/action_set.h b/src/mongo/db/auth/action_set.h index ba43583d75e..89291f7f6ff 100644 --- a/src/mongo/db/auth/action_set.h +++ b/src/mongo/db/auth/action_set.h @@ -25,7 +25,7 @@ namespace mongo { /* * An ActionSet is a bitmask of ActionTypes that represents a set of actions. - * These are the actions that a Capability can grant a principal to perform on a resource. + * These are the actions that a Privilege can grant a principal to perform on a resource. */ class ActionSet { public: @@ -51,7 +51,7 @@ namespace mongo { private: - // bitmask of actions this capability grants + // bitmask of actions this privilege grants std::bitset<ActionType::NUM_ACTION_TYPES> _actions; }; diff --git a/src/mongo/db/auth/authorization_manager.cpp b/src/mongo/db/auth/authorization_manager.cpp index cd72df21c9e..7755faadb7b 100644 --- a/src/mongo/db/auth/authorization_manager.cpp +++ b/src/mongo/db/auth/authorization_manager.cpp @@ -21,13 +21,13 @@ #include "mongo/base/init.h" #include "mongo/base/status.h" #include "mongo/client/dbclientinterface.h" -#include "mongo/db/auth/acquired_capability.h" +#include "mongo/db/auth/acquired_privilege.h" #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/capability_set.h" #include "mongo/db/auth/external_state_impl.h" #include "mongo/db/auth/principal.h" #include "mongo/db/auth/principal_set.h" +#include "mongo/db/auth/privilege_set.h" #include "mongo/db/client.h" #include "mongo/util/mongoutils/str.h" @@ -151,8 +151,8 @@ namespace mongo { return _authenticatedPrincipals.removeByName(principal->getName()); } - Status AuthorizationManager::acquireCapability(const AcquiredCapability& capability) { - const std::string& userName = capability.getPrincipal()->getName(); + Status AuthorizationManager::acquirePrivilege(const AcquiredPrivilege& privilege) { + const std::string& userName = privilege.getPrincipal()->getName(); if (!_authenticatedPrincipals.lookup(userName)) { return Status(ErrorCodes::UserNotFound, mongoutils::str::stream() @@ -161,7 +161,7 @@ namespace mongo { 0); } - _aquiredCapabilities.grantCapability(capability); + _acquiredPrivileges.grantPrivilege(privilege); return Status::OK(); } @@ -171,8 +171,8 @@ namespace mongo { _authenticatedPrincipals.add(internalPrincipal); ActionSet allActions; allActions.addAllActions(); - AcquiredCapability capability(Capability("*", allActions), internalPrincipal); - Status status = acquireCapability(capability); + AcquiredPrivilege privilege(Privilege("*", allActions), internalPrincipal); + Status status = acquirePrivilege(privilege); verify (status == Status::OK()); } @@ -205,34 +205,34 @@ namespace mongo { return !result.isEmpty(); } - Status AuthorizationManager::buildCapabilitySet(const std::string& dbname, - Principal* principal, - const BSONObj& privilegeDocument, - CapabilitySet* result) { + Status AuthorizationManager::buildPrivilegeSet(const std::string& dbname, + Principal* principal, + const BSONObj& privilegeDocument, + PrivilegeSet* result) { if (!privilegeDocument.hasField("privileges")) { // Old-style (v2.2 and prior) privilege document - return _buildCapabilitySetFromOldStylePrivilegeDocument(dbname, - principal, - privilegeDocument, - result); + return _buildPrivilegeSetFromOldStylePrivilegeDocument(dbname, + principal, + privilegeDocument, + result); } else { return Status(ErrorCodes::UnsupportedFormat, mongoutils::str::stream() << "Invalid privilege document received when" - "trying to extract capabilities: " << privilegeDocument, + "trying to extract privileges: " << privilegeDocument, 0); } } - Status AuthorizationManager::_buildCapabilitySetFromOldStylePrivilegeDocument( + Status AuthorizationManager::_buildPrivilegeSetFromOldStylePrivilegeDocument( const std::string& dbname, Principal* principal, const BSONObj& privilegeDocument, - CapabilitySet* result) { + PrivilegeSet* result) { if (!(privilegeDocument.hasField("user") && privilegeDocument.hasField("pwd"))) { return Status(ErrorCodes::UnsupportedFormat, mongoutils::str::stream() << "Invalid old-style privilege document " - "received when trying to extract capabilities: " + "received when trying to extract privileges: " << privilegeDocument, 0); } @@ -251,7 +251,7 @@ namespace mongo { if (dbname == "admin" || dbname == "local") { // Make all basic actions available on all databases - result->grantCapability(AcquiredCapability(Capability("*", actions), principal)); + result->grantPrivilege(AcquiredPrivilege(Privilege("*", actions), principal)); // Make server and cluster admin actions available on admin database. if (!readOnly) { actions.addAllActionsFromSet(serverAdminRoleActions); @@ -259,7 +259,7 @@ namespace mongo { } } - result->grantCapability(AcquiredCapability(Capability(dbname, actions), principal)); + result->grantPrivilege(AcquiredPrivilege(Privilege(dbname, actions), principal)); return Status::OK(); } @@ -270,14 +270,14 @@ namespace mongo { return &specialAdminPrincipal; } - const AcquiredCapability* capability; - capability = _aquiredCapabilities.getCapabilityForAction(resource, action); - if (capability) { - return capability->getPrincipal(); + const AcquiredPrivilege* privilege; + privilege = _acquiredPrivileges.getPrivilegeForAction(resource, action); + if (privilege) { + return privilege->getPrincipal(); } - capability = _aquiredCapabilities.getCapabilityForAction("*", action); - if (capability) { - return capability->getPrincipal(); + privilege = _acquiredPrivileges.getPrivilegeForAction("*", action); + if (privilege) { + return privilege->getPrincipal(); } return NULL; // Not authorized diff --git a/src/mongo/db/auth/authorization_manager.h b/src/mongo/db/auth/authorization_manager.h index 2d4c9bdd0b9..4b47f27dddc 100644 --- a/src/mongo/db/auth/authorization_manager.h +++ b/src/mongo/db/auth/authorization_manager.h @@ -21,19 +21,19 @@ #include "mongo/base/disallow_copying.h" #include "mongo/base/status.h" #include "mongo/client/dbclientinterface.h" -#include "mongo/db/auth/acquired_capability.h" +#include "mongo/db/auth/acquired_privilege.h" #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/capability_set.h" #include "mongo/db/auth/external_state.h" #include "mongo/db/auth/principal.h" #include "mongo/db/auth/principal_set.h" +#include "mongo/db/auth/privilege_set.h" namespace mongo { /** * Contains all the authorization logic for a single client connection. It contains a set of - * the principals which have been authenticated, as well as a set of capabilities that have been + * the principals which have been authenticated, as well as a set of privileges that have been * granted by those principals to perform various actions. * An AuthorizationManager object is present within every mongo::Client object, therefore there * is one per thread that corresponds to an incoming client connection. @@ -52,18 +52,18 @@ namespace mongo { // _authenticatedPrincipals set. Status removeAuthorizedPrincipal(const Principal* principal); - // Grant this connection the given capability. - Status acquireCapability(const AcquiredCapability& capability); + // Grant this connection the given privilege. + Status acquirePrivilege(const AcquiredPrivilege& privilege); // This should be called when the connection gets authenticated as the internal user. - // This grants a capability on all the actions for the internal role, with the + // This grants a privilege on all the actions for the internal role, with the // internalPrincipal as the principal. void grantInternalAuthorization(); - // Checks if this connection has the capabilities required to perform the given action + // Checks if this connection has the privileges required to perform the given action // on the given resource. Contains all the authorization logic including handling things // like the localhost exception. If it is authorized, returns the principal that granted - // the needed capability. Returns NULL if not authorized. If the action is authorized but + // the needed privilege. Returns NULL if not authorized. If the action is authorized but // not because of a standard user Principal but for a special reason such as the localhost // exception, it returns a pointer to specialAdminPrincipal. const Principal* checkAuthorization(const std::string& resource, ActionType action) const; @@ -78,26 +78,27 @@ namespace mongo { // Returns true if there exists at least one privilege document in the given database. static bool hasPrivilegeDocument(DBClientBase* conn, const std::string& dbname); - // Parses the privilege document and returns a CapabilitySet of all the Capabilities that + // Parses the privilege document and returns a PrivilegeSet of all the Capabilities that // the privilege document grants. - static Status buildCapabilitySet(const std::string& dbname, - Principal* principal, - const BSONObj& privilegeDocument, - CapabilitySet* result); + static Status buildPrivilegeSet(const std::string& dbname, + Principal* principal, + const BSONObj& privilegeDocument, + PrivilegeSet* result); private: - // Parses the old-style (pre 2.4) privilege document and returns a CapabilitySet of all the - // Capabilities that the privilege document grants. - static Status _buildCapabilitySetFromOldStylePrivilegeDocument(const std::string& dbname, - Principal* principal, - const BSONObj& privilegeDocument, - CapabilitySet* result); + // Parses the old-style (pre 2.4) privilege document and returns a PrivilegeSet of all the + // Privileges that the privilege document grants. + static Status _buildPrivilegeSetFromOldStylePrivilegeDocument( + const std::string& dbname, + Principal* principal, + const BSONObj& privilegeDocument, + PrivilegeSet* result); scoped_ptr<ExternalState> _externalState; - // All the capabilities that have been acquired by the authenticated principals. - CapabilitySet _aquiredCapabilities; + // All the privileges that have been acquired by the authenticated principals. + PrivilegeSet _acquiredPrivileges; // All principals who have been authenticated on this connection PrincipalSet _authenticatedPrincipals; }; diff --git a/src/mongo/db/auth/authorization_manager_test.cpp b/src/mongo/db/auth/authorization_manager_test.cpp index 1fecf4f020f..8d8cda7b41a 100644 --- a/src/mongo/db/auth/authorization_manager_test.cpp +++ b/src/mongo/db/auth/authorization_manager_test.cpp @@ -30,12 +30,12 @@ namespace mongo { namespace { - TEST(AuthorizationManagerTest, AcquireCapabilityAndCheckAuthorization) { + TEST(AuthorizationManagerTest, AcquirePrivilegeAndCheckAuthorization) { Principal* principal = new Principal("Spencer"); ActionSet actions; actions.addAction(ActionType::insert); - AcquiredCapability writeCapability(Capability("test", actions), principal); - AcquiredCapability allDBsWriteCapability(Capability("*", actions), principal); + AcquiredPrivilege writePrivilege(Privilege("test", actions), principal); + AcquiredPrivilege allDBsWritePrivilege(Privilege("*", actions), principal); ExternalStateMock* externalState = new ExternalStateMock(); AuthorizationManager authManager(externalState); @@ -47,13 +47,13 @@ namespace { ASSERT_NULL(authManager.checkAuthorization("test", ActionType::insert)); ASSERT_EQUALS(ErrorCodes::UserNotFound, - authManager.acquireCapability(writeCapability).code()); + authManager.acquirePrivilege(writePrivilege).code()); authManager.addAuthorizedPrincipal(principal); - ASSERT_OK(authManager.acquireCapability(writeCapability)); + ASSERT_OK(authManager.acquirePrivilege(writePrivilege)); ASSERT_EQUALS(principal, authManager.checkAuthorization("test", ActionType::insert)); ASSERT_NULL(authManager.checkAuthorization("otherDb", ActionType::insert)); - ASSERT_OK(authManager.acquireCapability(allDBsWriteCapability)); + ASSERT_OK(authManager.acquirePrivilege(allDBsWritePrivilege)); ASSERT_EQUALS(principal, authManager.checkAuthorization("otherDb", ActionType::insert)); } @@ -70,55 +70,55 @@ namespace { ASSERT_NON_NULL(authManager.checkAuthorization("test", ActionType::replSetHeartbeat)); } - TEST(AuthorizationManagerTest, GetCapabilitiesFromPrivilegeDocument) { + TEST(AuthorizationManagerTest, GetPrivilegesFromPrivilegeDocument) { Principal* principal = new Principal("Spencer"); BSONObj invalid; BSONObj readWrite = BSON("user" << "Spencer" << "pwd" << "passwordHash"); BSONObj readOnly = BSON("user" << "Spencer" << "pwd" << "passwordHash" << "readOnly" << true); - CapabilitySet capabilitySet; + PrivilegeSet privilegeSet; ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, - AuthorizationManager::buildCapabilitySet("test", + AuthorizationManager::buildPrivilegeSet("test", principal, invalid, - &capabilitySet).code()); + &privilegeSet).code()); - ASSERT_OK(AuthorizationManager::buildCapabilitySet("test", + ASSERT_OK(AuthorizationManager::buildPrivilegeSet("test", principal, readOnly, - &capabilitySet)); - ASSERT_NULL(capabilitySet.getCapabilityForAction("test", ActionType::insert)); - ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("test", ActionType::find)); + &privilegeSet)); + ASSERT_NULL(privilegeSet.getPrivilegeForAction("test", ActionType::insert)); + ASSERT_NON_NULL(privilegeSet.getPrivilegeForAction("test", ActionType::find)); - ASSERT_OK(AuthorizationManager::buildCapabilitySet("test", + ASSERT_OK(AuthorizationManager::buildPrivilegeSet("test", principal, readWrite, - &capabilitySet)); - ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("test", ActionType::find)); - ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("test", ActionType::insert)); - ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("test", ActionType::userAdmin)); - ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("test", ActionType::compact)); - ASSERT_NULL(capabilitySet.getCapabilityForAction("test", ActionType::shutdown)); - ASSERT_NULL(capabilitySet.getCapabilityForAction("test", ActionType::addShard)); - - ASSERT_NULL(capabilitySet.getCapabilityForAction("admin", ActionType::find)); - ASSERT_NULL(capabilitySet.getCapabilityForAction("*", ActionType::find)); - ASSERT_OK(AuthorizationManager::buildCapabilitySet("admin", + &privilegeSet)); + ASSERT_NON_NULL(privilegeSet.getPrivilegeForAction("test", ActionType::find)); + ASSERT_NON_NULL(privilegeSet.getPrivilegeForAction("test", ActionType::insert)); + ASSERT_NON_NULL(privilegeSet.getPrivilegeForAction("test", ActionType::userAdmin)); + ASSERT_NON_NULL(privilegeSet.getPrivilegeForAction("test", ActionType::compact)); + ASSERT_NULL(privilegeSet.getPrivilegeForAction("test", ActionType::shutdown)); + ASSERT_NULL(privilegeSet.getPrivilegeForAction("test", ActionType::addShard)); + + ASSERT_NULL(privilegeSet.getPrivilegeForAction("admin", ActionType::find)); + ASSERT_NULL(privilegeSet.getPrivilegeForAction("*", ActionType::find)); + ASSERT_OK(AuthorizationManager::buildPrivilegeSet("admin", principal, readOnly, - &capabilitySet)); - ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("admin", ActionType::find)); - ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("*", ActionType::find)); + &privilegeSet)); + ASSERT_NON_NULL(privilegeSet.getPrivilegeForAction("admin", ActionType::find)); + ASSERT_NON_NULL(privilegeSet.getPrivilegeForAction("*", ActionType::find)); - ASSERT_NULL(capabilitySet.getCapabilityForAction("admin", ActionType::insert)); - ASSERT_NULL(capabilitySet.getCapabilityForAction("*", ActionType::insert)); - ASSERT_OK(AuthorizationManager::buildCapabilitySet("admin", + ASSERT_NULL(privilegeSet.getPrivilegeForAction("admin", ActionType::insert)); + ASSERT_NULL(privilegeSet.getPrivilegeForAction("*", ActionType::insert)); + ASSERT_OK(AuthorizationManager::buildPrivilegeSet("admin", principal, readWrite, - &capabilitySet)); - ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("admin", ActionType::insert)); - ASSERT_NON_NULL(capabilitySet.getCapabilityForAction("*", ActionType::insert)); + &privilegeSet)); + ASSERT_NON_NULL(privilegeSet.getPrivilegeForAction("admin", ActionType::insert)); + ASSERT_NON_NULL(privilegeSet.getPrivilegeForAction("*", ActionType::insert)); } } // namespace diff --git a/src/mongo/db/auth/capability_set.cpp b/src/mongo/db/auth/capability_set.cpp deleted file mode 100644 index 98faf05102a..00000000000 --- a/src/mongo/db/auth/capability_set.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/** -* Copyright (C) 2012 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "mongo/pch.h" - -#include "mongo/db/auth/capability_set.h" - -#include <map> -#include <string> - -#include "mongo/db/auth/acquired_capability.h" -#include "mongo/db/auth/action_set.h" -#include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/principal.h" - -namespace mongo { - - void CapabilitySet::grantCapability(const AcquiredCapability& capability) { - _capabilities.insert(std::make_pair(capability.getCapability().getResource(), capability)); - } - - const AcquiredCapability* CapabilitySet::getCapabilityForAction( - const std::string& resource, const ActionType& action) const { - CapabilitySetConstRange range; - CapabilityRangeConstIterator it; - - range = _capabilities.equal_range(resource); - for (it = range.first; it != range.second; ++it) { - const AcquiredCapability& capability = it->second; - if (capability.getCapability().includesAction(action)) { - return &capability; - } - } - return NULL; - } - - void CapabilitySet::revokeCapabilitiesFromPrincipal(Principal* principal) { - CapabilityRangeIterator it = _capabilities.begin(); - - while (it != _capabilities.end()) { - CapabilityRangeIterator current = it; - ++it; // Must advance now because erase will invalidate the iterator - AcquiredCapability& capability = current->second; - if (capability.getPrincipal() == principal) { - _capabilities.erase(current); - } - } - } - -} // namespace mongo diff --git a/src/mongo/db/auth/capability_set.h b/src/mongo/db/auth/capability_set.h deleted file mode 100644 index 07163d77bce..00000000000 --- a/src/mongo/db/auth/capability_set.h +++ /dev/null @@ -1,70 +0,0 @@ -/** -* Copyright (C) 2012 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#pragma once - -#include <map> -#include <string> - -#include "mongo/base/disallow_copying.h" -#include "mongo/db/auth/acquired_capability.h" -#include "mongo/db/auth/action_set.h" -#include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/capability.h" -#include "mongo/db/auth/principal.h" - -namespace mongo { - - /** - * A collection of capabilities describing which authenticated principals bestow the client - * the ability to perform various actions on specific resources. Since every capability - * comes from an authenticated principal, removing that principal can remove all capabilities - * that that principal granted. - * This class does not do any locking/synchronization, the consumer will be responsible for - * synchronizing access. - */ - class CapabilitySet { - MONGO_DISALLOW_COPYING(CapabilitySet); - public: - CapabilitySet(){} - ~CapabilitySet(){} - - void grantCapability(const AcquiredCapability& capability); - void revokeCapabilitiesFromPrincipal(Principal* principal); - - // Returns the first capability found that grants the given action on the given resource. - // Returns NULL if there is no such capability. - // Ownership of the returned Capability remains with the CapabilitySet. The pointer - // returned is only guaranteed to remain valid until the next non-const method is called - // on the CapabilitySet. - const AcquiredCapability* getCapabilityForAction(const std::string& resource, - const ActionType& action) const; - - private: - - // Key is the resource the capability is on. - typedef std::multimap<const std::string, AcquiredCapability> CapabilityMap; - typedef CapabilityMap::iterator CapabilityRangeIterator; - typedef std::pair<CapabilityRangeIterator, CapabilityRangeIterator> CapabilitySetRange; - typedef CapabilityMap::const_iterator CapabilityRangeConstIterator; - typedef std::pair<CapabilityRangeConstIterator, CapabilityRangeConstIterator> - CapabilitySetConstRange; - - // Maps resource to capabilities - CapabilityMap _capabilities; - }; - -} // namespace mongo diff --git a/src/mongo/db/auth/capability_set_test.cpp b/src/mongo/db/auth/capability_set_test.cpp deleted file mode 100644 index 5d91c5361c1..00000000000 --- a/src/mongo/db/auth/capability_set_test.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright 2012 10gen Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Unit tests of the CapabilitySet type. - */ - -#include "mongo/db/auth/acquired_capability.h" -#include "mongo/db/auth/action_set.h" -#include "mongo/db/auth/capability_set.h" -#include "mongo/unittest/unittest.h" - -namespace mongo { -namespace { - - TEST(CapabilitySetTest, CapabilitySet) { - CapabilitySet capSet; - ActionSet actions; - Principal user1("user1"); - Principal user2("user2"); - - ASSERT_OK(ActionSet::parseActionSetFromString("find,update", &actions)); - AcquiredCapability fooUser(Capability("foo", actions), &user2); - - ASSERT_OK(ActionSet::parseActionSetFromString("find,update,userAdmin,remove", &actions)); - AcquiredCapability fooUser2(Capability("foo", actions), &user1); - - ASSERT_OK(ActionSet::parseActionSetFromString("find,update", &actions)); - AcquiredCapability barUser(Capability("bar", actions), &user1); - - ASSERT_OK(ActionSet::parseActionSetFromString("find", &actions)); - AcquiredCapability barReadOnly(Capability("bar", actions), &user2); - - - const AcquiredCapability* capPtr; - // No capabilities - ASSERT(!capSet.getCapabilityForAction("foo", ActionType::find)); - - capSet.grantCapability(fooUser); - capPtr = capSet.getCapabilityForAction("foo", ActionType::find); - ASSERT_TRUE(capPtr->getCapability().includesAction(ActionType::find)); - ASSERT_FALSE(capPtr->getCapability().includesAction(ActionType::remove)); - - ASSERT(!capSet.getCapabilityForAction("foo", ActionType::remove)); - - capSet.grantCapability(fooUser2); - capPtr = capSet.getCapabilityForAction("foo", ActionType::userAdmin); - ASSERT_TRUE(capPtr->getCapability().includesAction(ActionType::find)); - ASSERT_TRUE(capPtr->getCapability().includesAction(ActionType::remove)); - - // No capabilities - ASSERT(!capSet.getCapabilityForAction("bar", ActionType::find)); - - capSet.grantCapability(barReadOnly); - capPtr = capSet.getCapabilityForAction("bar", ActionType::find); - ASSERT_TRUE(capPtr->getCapability().includesAction(ActionType::find)); - ASSERT_FALSE(capPtr->getCapability().includesAction(ActionType::update)); - ASSERT_FALSE(capPtr->getCapability().includesAction(ActionType::remove)); - - ASSERT(!capSet.getCapabilityForAction("bar", ActionType::update)); - - capSet.grantCapability(barUser); - capPtr = capSet.getCapabilityForAction("bar", ActionType::update); - ASSERT_TRUE(capPtr->getCapability().includesAction(ActionType::find)); - ASSERT_TRUE(capPtr->getCapability().includesAction(ActionType::update)); - ASSERT_FALSE(capPtr->getCapability().includesAction(ActionType::remove)); - - // Now let's start revoking capabilities - capSet.revokeCapabilitiesFromPrincipal(&user1); - - capPtr = capSet.getCapabilityForAction("foo", ActionType::find); - ASSERT_TRUE(capPtr->getCapability().includesAction(ActionType::find)); - ASSERT_FALSE(capPtr->getCapability().includesAction(ActionType::remove)); - - capPtr = capSet.getCapabilityForAction("bar", ActionType::find); - ASSERT_TRUE(capPtr->getCapability().includesAction(ActionType::find)); - ASSERT_FALSE(capPtr->getCapability().includesAction(ActionType::update)); - ASSERT_FALSE(capPtr->getCapability().includesAction(ActionType::remove)); - - - capSet.revokeCapabilitiesFromPrincipal(&user2); - ASSERT(!capSet.getCapabilityForAction("foo", ActionType::find)); - ASSERT(!capSet.getCapabilityForAction("bar", ActionType::find)); - } - -} // namespace -} // namespace mongo diff --git a/src/mongo/db/auth/generate_action_types.py b/src/mongo/db/auth/generate_action_types.py index 32f864ac736..f915b730814 100755 --- a/src/mongo/db/auth/generate_action_types.py +++ b/src/mongo/db/auth/generate_action_types.py @@ -135,7 +135,7 @@ namespace mongo { Status ActionType::parseActionFromString(const std::string& action, ActionType* result) { %(fromStringIfStatements)s return Status(ErrorCodes::FailedToParse, - mongoutils::str::stream() << "Unrecognized action capability string: " + mongoutils::str::stream() << "Unrecognized action privilege string: " << action, 0); } diff --git a/src/mongo/db/auth/capability.cpp b/src/mongo/db/auth/privilege.cpp index 5e09933075b..db03c8d72d4 100644 --- a/src/mongo/db/auth/capability.cpp +++ b/src/mongo/db/auth/privilege.cpp @@ -14,7 +14,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "mongo/db/auth/capability.h" +#include "mongo/db/auth/privilege.h" #include <string> @@ -24,11 +24,10 @@ namespace mongo { - Capability::Capability(const std::string& resource, ActionSet actions) : - _resource(resource), - _actions(actions) {} + Privilege::Privilege(const std::string& resource, ActionSet actions) : + _resource(resource), _actions(actions) {} - bool Capability::includesAction(const ActionType& action) const { + bool Privilege::includesAction(const ActionType& action) const { return _actions.contains(action); } diff --git a/src/mongo/db/auth/capability.h b/src/mongo/db/auth/privilege.h index d8f76c0d6da..0ad0f8e20e6 100644 --- a/src/mongo/db/auth/capability.h +++ b/src/mongo/db/auth/privilege.h @@ -27,23 +27,23 @@ namespace mongo { /** * A representation of the permission to perform a set of actions on a specific resource. */ - class Capability { + class Privilege { public: - Capability(const std::string& resource, ActionSet actions); - ~Capability() {} + Privilege(const std::string& resource, ActionSet actions); + ~Privilege() {} const std::string& getResource() const { return _resource; } const ActionSet& getActions() const { return _actions; } - // Checks if the given action is present in the Capability. + // Checks if the given action is present in the Privilege. bool includesAction(const ActionType& action) const; private: std::string _resource; - ActionSet _actions; // bitmask of actions this capability grants + ActionSet _actions; // bitmask of actions this privilege grants }; } // namespace mongo diff --git a/src/mongo/db/auth/privilege_set.cpp b/src/mongo/db/auth/privilege_set.cpp new file mode 100644 index 00000000000..192f57c8a03 --- /dev/null +++ b/src/mongo/db/auth/privilege_set.cpp @@ -0,0 +1,63 @@ +/** +* Copyright (C) 2012 10gen Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "mongo/pch.h" + +#include "mongo/db/auth/privilege_set.h" + +#include <map> +#include <string> + +#include "mongo/db/auth/acquired_privilege.h" +#include "mongo/db/auth/action_set.h" +#include "mongo/db/auth/action_type.h" +#include "mongo/db/auth/principal.h" + +namespace mongo { + + void PrivilegeSet::grantPrivilege(const AcquiredPrivilege& privilege) { + _privileges.insert(std::make_pair(privilege.getPrivilege().getResource(), privilege)); + } + + const AcquiredPrivilege* PrivilegeSet::getPrivilegeForAction(const std::string& resource, + const ActionType& action) const { + PrivilegeSetConstRange range; + PrivilegeRangeConstIterator it; + + range = _privileges.equal_range(resource); + for (it = range.first; it != range.second; ++it) { + const AcquiredPrivilege& privilege = it->second; + if (privilege.getPrivilege().includesAction(action)) { + return &privilege; + } + } + return NULL; + } + + void PrivilegeSet::revokePrivilegesFromPrincipal(Principal* principal) { + PrivilegeRangeIterator it = _privileges.begin(); + + while (it != _privileges.end()) { + PrivilegeRangeIterator current = it; + ++it; // Must advance now because erase will invalidate the iterator + AcquiredPrivilege& privilege = current->second; + if (privilege.getPrincipal() == principal) { + _privileges.erase(current); + } + } + } + +} // namespace mongo diff --git a/src/mongo/db/auth/privilege_set.h b/src/mongo/db/auth/privilege_set.h new file mode 100644 index 00000000000..8cf75dcc421 --- /dev/null +++ b/src/mongo/db/auth/privilege_set.h @@ -0,0 +1,70 @@ +/** +* Copyright (C) 2012 10gen Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include <map> +#include <string> + +#include "mongo/base/disallow_copying.h" +#include "mongo/db/auth/acquired_privilege.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/principal.h" + +namespace mongo { + + /** + * A collection of privileges describing which authenticated principals bestow the client + * the ability to perform various actions on specific resources. Since every privilege + * comes from an authenticated principal, removing that principal can remove all privileges + * that that principal granted. + * This class does not do any locking/synchronization, the consumer will be responsible for + * synchronizing access. + */ + class PrivilegeSet { + MONGO_DISALLOW_COPYING(PrivilegeSet); + public: + PrivilegeSet(){} + ~PrivilegeSet(){} + + void grantPrivilege(const AcquiredPrivilege& privilege); + void revokePrivilegesFromPrincipal(Principal* principal); + + // Returns the first privilege found that grants the given action on the given resource. + // Returns NULL if there is no such privilege. + // Ownership of the returned Privilege remains with the PrivilegeSet. The pointer + // returned is only guaranteed to remain valid until the next non-const method is called + // on the PrivilegeSet. + const AcquiredPrivilege* getPrivilegeForAction(const std::string& resource, + const ActionType& action) const; + + private: + + // Key is the resource the privilege is on. + typedef std::multimap<const std::string, AcquiredPrivilege> PrivilegeMap; + typedef PrivilegeMap::iterator PrivilegeRangeIterator; + typedef std::pair<PrivilegeRangeIterator, PrivilegeRangeIterator> PrivilegeSetRange; + typedef PrivilegeMap::const_iterator PrivilegeRangeConstIterator; + typedef std::pair<PrivilegeRangeConstIterator, PrivilegeRangeConstIterator> + PrivilegeSetConstRange; + + // Maps resource to privileges + PrivilegeMap _privileges; + }; + +} // namespace mongo diff --git a/src/mongo/db/auth/privilege_set_test.cpp b/src/mongo/db/auth/privilege_set_test.cpp new file mode 100644 index 00000000000..5676a2a3a26 --- /dev/null +++ b/src/mongo/db/auth/privilege_set_test.cpp @@ -0,0 +1,99 @@ +/* Copyright 2012 10gen Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Unit tests of the PrivilegeSet type. + */ + +#include "mongo/db/auth/acquired_privilege.h" +#include "mongo/db/auth/action_set.h" +#include "mongo/db/auth/privilege_set.h" +#include "mongo/unittest/unittest.h" + +namespace mongo { +namespace { + + TEST(PrivilegeSetTest, PrivilegeSet) { + PrivilegeSet capSet; + ActionSet actions; + Principal user1("user1"); + Principal user2("user2"); + + ASSERT_OK(ActionSet::parseActionSetFromString("find,update", &actions)); + AcquiredPrivilege fooUser(Privilege("foo", actions), &user2); + + ASSERT_OK(ActionSet::parseActionSetFromString("find,update,userAdmin,remove", &actions)); + AcquiredPrivilege fooUser2(Privilege("foo", actions), &user1); + + ASSERT_OK(ActionSet::parseActionSetFromString("find,update", &actions)); + AcquiredPrivilege barUser(Privilege("bar", actions), &user1); + + ASSERT_OK(ActionSet::parseActionSetFromString("find", &actions)); + AcquiredPrivilege barReadOnly(Privilege("bar", actions), &user2); + + + const AcquiredPrivilege* capPtr; + // No capabilities + ASSERT(!capSet.getPrivilegeForAction("foo", ActionType::find)); + + capSet.grantPrivilege(fooUser); + capPtr = capSet.getPrivilegeForAction("foo", ActionType::find); + ASSERT_TRUE(capPtr->getPrivilege().includesAction(ActionType::find)); + ASSERT_FALSE(capPtr->getPrivilege().includesAction(ActionType::remove)); + + ASSERT(!capSet.getPrivilegeForAction("foo", ActionType::remove)); + + capSet.grantPrivilege(fooUser2); + capPtr = capSet.getPrivilegeForAction("foo", ActionType::userAdmin); + ASSERT_TRUE(capPtr->getPrivilege().includesAction(ActionType::find)); + ASSERT_TRUE(capPtr->getPrivilege().includesAction(ActionType::remove)); + + // No capabilities + ASSERT(!capSet.getPrivilegeForAction("bar", ActionType::find)); + + capSet.grantPrivilege(barReadOnly); + capPtr = capSet.getPrivilegeForAction("bar", ActionType::find); + ASSERT_TRUE(capPtr->getPrivilege().includesAction(ActionType::find)); + ASSERT_FALSE(capPtr->getPrivilege().includesAction(ActionType::update)); + ASSERT_FALSE(capPtr->getPrivilege().includesAction(ActionType::remove)); + + ASSERT(!capSet.getPrivilegeForAction("bar", ActionType::update)); + + capSet.grantPrivilege(barUser); + capPtr = capSet.getPrivilegeForAction("bar", ActionType::update); + ASSERT_TRUE(capPtr->getPrivilege().includesAction(ActionType::find)); + ASSERT_TRUE(capPtr->getPrivilege().includesAction(ActionType::update)); + ASSERT_FALSE(capPtr->getPrivilege().includesAction(ActionType::remove)); + + // Now let's start revoking capabilities + capSet.revokePrivilegesFromPrincipal(&user1); + + capPtr = capSet.getPrivilegeForAction("foo", ActionType::find); + ASSERT_TRUE(capPtr->getPrivilege().includesAction(ActionType::find)); + ASSERT_FALSE(capPtr->getPrivilege().includesAction(ActionType::remove)); + + capPtr = capSet.getPrivilegeForAction("bar", ActionType::find); + ASSERT_TRUE(capPtr->getPrivilege().includesAction(ActionType::find)); + ASSERT_FALSE(capPtr->getPrivilege().includesAction(ActionType::update)); + ASSERT_FALSE(capPtr->getPrivilege().includesAction(ActionType::remove)); + + + capSet.revokePrivilegesFromPrincipal(&user2); + ASSERT(!capSet.getPrivilegeForAction("foo", ActionType::find)); + ASSERT(!capSet.getPrivilegeForAction("bar", ActionType::find)); + } + +} // namespace +} // namespace mongo |