summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@10gen.com>2013-05-16 18:04:07 -0400
committerSpencer T Brody <spencer@10gen.com>2013-05-23 12:09:58 -0400
commitc95bf3ff714f9dad17288e3cb8dcfab7d7ebe6fc (patch)
tree6e0d4b26840c53a5d184abeb41c6e3f85beef917
parent23a185462b83a4f0f7ea5f3ada89ff819313c992 (diff)
downloadmongo-c95bf3ff714f9dad17288e3cb8dcfab7d7ebe6fc.tar.gz
SERVER-9518 Initial implementation of new User class
-rw-r--r--src/mongo/db/auth/SConscript3
-rw-r--r--src/mongo/db/auth/role_graph.cpp33
-rw-r--r--src/mongo/db/auth/role_name.cpp24
-rw-r--r--src/mongo/db/auth/role_name.h30
-rw-r--r--src/mongo/db/auth/user.cpp108
-rw-r--r--src/mongo/db/auth/user.h163
6 files changed, 326 insertions, 35 deletions
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript
index 55c14bd1258..06f4349b60d 100644
--- a/src/mongo/db/auth/SConscript
+++ b/src/mongo/db/auth/SConscript
@@ -19,7 +19,8 @@ env.StaticLibrary('authcore', ['action_set.cpp',
'principal_name.cpp',
'principal_set.cpp',
'privilege.cpp',
- 'privilege_set.cpp'],
+ 'privilege_set.cpp',
+ 'user.cpp'],
LIBDEPS=['$BUILD_DIR/mongo/base/base',
'$BUILD_DIR/mongo/bson',
'$BUILD_DIR/mongo/stringutils'])
diff --git a/src/mongo/db/auth/role_graph.cpp b/src/mongo/db/auth/role_graph.cpp
index da4c69283c7..95662c4621f 100644
--- a/src/mongo/db/auth/role_graph.cpp
+++ b/src/mongo/db/auth/role_graph.cpp
@@ -27,39 +27,6 @@ namespace mongo {
namespace {
PrivilegeVector emptyPrivilegeVector;
-
- class RoleNameSetIterator : public RoleNameIterator::Impl {
- MONGO_DISALLOW_COPYING(RoleNameSetIterator);
-
- public:
- RoleNameSetIterator(unordered_set<RoleName>::const_iterator begin,
- unordered_set<RoleName>::const_iterator end) :
- _begin(begin), _end(end) {}
-
- virtual ~RoleNameSetIterator() {};
-
- virtual bool more() const {
- return _begin != _end;
- }
-
- virtual const RoleName& next() {
- const RoleName& toReturn = get();
- ++_begin;
- return toReturn;
- }
-
- virtual const RoleName& get() const {
- return *_begin;
- }
-
- private:
- virtual Impl* doClone() const {
- return new RoleNameSetIterator(_begin, _end);
- }
-
- unordered_set<RoleName>::const_iterator _begin;
- unordered_set<RoleName>::const_iterator _end;
- };
} // namespace
RoleGraph::RoleGraph() {};
diff --git a/src/mongo/db/auth/role_name.cpp b/src/mongo/db/auth/role_name.cpp
index d691e826f77..8c66232abb7 100644
--- a/src/mongo/db/auth/role_name.cpp
+++ b/src/mongo/db/auth/role_name.cpp
@@ -36,4 +36,28 @@ namespace mongo {
_splitPoint = role.size();
}
+ RoleNameSetIterator::RoleNameSetIterator(const unordered_set<RoleName>::const_iterator& begin,
+ const unordered_set<RoleName>::const_iterator& end) :
+ _begin(begin), _end(end) {}
+
+ RoleNameSetIterator::~RoleNameSetIterator() {};
+
+ bool RoleNameSetIterator::more() const {
+ return _begin != _end;
+ }
+
+ const RoleName& RoleNameSetIterator::next() {
+ const RoleName& toReturn = get();
+ ++_begin;
+ return toReturn;
+ }
+
+ const RoleName& RoleNameSetIterator::get() const {
+ return *_begin;
+ }
+
+ RoleNameIterator::Impl* RoleNameSetIterator::doClone() const {
+ return new RoleNameSetIterator(_begin, _end);
+ }
+
} // namespace mongo
diff --git a/src/mongo/db/auth/role_name.h b/src/mongo/db/auth/role_name.h
index 12062c83a5d..130f7a98e70 100644
--- a/src/mongo/db/auth/role_name.h
+++ b/src/mongo/db/auth/role_name.h
@@ -23,6 +23,7 @@
#include "mongo/base/disallow_copying.h"
#include "mongo/base/string_data.h"
#include "mongo/platform/hash_namespace.h"
+#include "mongo/platform/unordered_set.h"
#include "mongo/util/assert_util.h"
namespace mongo {
@@ -118,7 +119,7 @@ namespace mongo {
boost::scoped_ptr<Impl> _impl;
};
-} // namespace mongo
+} // namespace mongo
// Define hash function for RoleNames so they can be keys in std::unordered_map
MONGO_HASH_NAMESPACE_START
@@ -128,3 +129,30 @@ MONGO_HASH_NAMESPACE_START
}
};
MONGO_HASH_NAMESPACE_END
+
+namespace mongo {
+
+ // RoleNameIterator for iterating over an unordered_set of RoleNames.
+ class RoleNameSetIterator : public RoleNameIterator::Impl {
+ MONGO_DISALLOW_COPYING(RoleNameSetIterator);
+
+ public:
+ RoleNameSetIterator(const unordered_set<RoleName>::const_iterator& begin,
+ const unordered_set<RoleName>::const_iterator& end);
+
+ virtual ~RoleNameSetIterator();
+
+ virtual bool more() const;
+
+ virtual const RoleName& next();
+
+ virtual const RoleName& get() const;
+
+ private:
+ virtual Impl* doClone() const;
+
+ unordered_set<RoleName>::const_iterator _begin;
+ unordered_set<RoleName>::const_iterator _end;
+ };
+
+} // namespace mongo
diff --git a/src/mongo/db/auth/user.cpp b/src/mongo/db/auth/user.cpp
new file mode 100644
index 00000000000..b4c87738b9f
--- /dev/null
+++ b/src/mongo/db/auth/user.cpp
@@ -0,0 +1,108 @@
+/* Copyright 2013 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.
+ */
+
+#include "mongo/db/auth/user.h"
+
+#include <vector>
+
+#include "mongo/db/auth/principal_name.h"
+#include "mongo/db/auth/privilege.h"
+#include "mongo/db/auth/role_name.h"
+#include "mongo/platform/atomic_word.h"
+
+namespace mongo {
+
+ User::User(const UserName& name) : _name(name), _refCount(0), _isValid(1) {}
+ User::~User() {}
+
+ const UserName& User::getName() const {
+ return _name;
+ }
+
+ const RoleNameIterator User::getRoles() const {
+ return RoleNameIterator(new RoleNameSetIterator(_roles.begin(), _roles.end()));
+ }
+
+ bool User::isValid() const {
+ return _isValid.loadRelaxed() == 1;
+ }
+
+ uint32_t User::getRefCount() const {
+ return _refCount;
+ }
+
+ const ActionSet User::getActionsForResource(const std::string& resource) const {
+ unordered_map<string, Privilege>::const_iterator it = _privileges.find(resource);
+ if (it == _privileges.end()) {
+ return ActionSet();
+ }
+ return it->second.getActions();
+ }
+
+ void User::copyFrom(const User& other) {
+ _name = other._name;
+ _privileges = other._privileges;
+ _roles = other._roles;
+ _credentials = other._credentials;
+ _refCount = other._refCount;
+ _isValid= other._isValid;
+ }
+
+ void User::setCredentials(const CredentialData& credentials) {
+ _credentials = credentials;
+ }
+
+ void User::addRole(const RoleName& role) {
+ _roles.insert(role);
+ }
+
+ void User::addRoles(const std::vector<RoleName>& roles) {
+ for (std::vector<RoleName>::const_iterator it = roles.begin(); it != roles.end(); ++it) {
+ _roles.insert(*it);
+ }
+ }
+
+ void User::addPrivilege(const Privilege& privilegeToAdd) {
+ ResourcePrivilegeMap::iterator it = _privileges.find(privilegeToAdd.getResource());
+ if (it == _privileges.end()) {
+ // No privilege exists yet for this resource
+ _privileges.insert(std::make_pair(privilegeToAdd.getResource(), privilegeToAdd));
+ } else {
+ dassert(it->first == privilegeToAdd.getResource());
+ it->second.addActions(privilegeToAdd.getActions());
+ }
+ }
+
+ void User::addPrivileges(const PrivilegeVector& privileges) {
+ for (PrivilegeVector::const_iterator it = privileges.begin();
+ it != privileges.end(); ++it) {
+ addPrivilege(*it);
+ }
+ }
+
+ void User::invalidate() {
+ _isValid.store(0);
+ }
+
+ void User::incrementRefCount() {
+ ++_refCount;
+ }
+
+ void User::decrementRefCount() {
+ dassert(_refCount > 0);
+ --_refCount;
+ }
+} // namespace mongo
diff --git a/src/mongo/db/auth/user.h b/src/mongo/db/auth/user.h
new file mode 100644
index 00000000000..d5dd49cb076
--- /dev/null
+++ b/src/mongo/db/auth/user.h
@@ -0,0 +1,163 @@
+/* Copyright 2013 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.
+ */
+
+#pragma once
+
+#include <vector>
+
+#include "mongo/base/disallow_copying.h"
+#include "mongo/db/auth/principal_name.h"
+#include "mongo/db/auth/privilege.h"
+#include "mongo/db/auth/role_name.h"
+#include "mongo/platform/atomic_word.h"
+#include "mongo/platform/unordered_map.h"
+#include "mongo/platform/unordered_set.h"
+
+namespace mongo {
+
+ typedef PrincipalName UserName; // TODO: remove this and rename PrincipalName->UserName everywhere
+
+ /**
+ * Represents a MongoDB user. Stores information about the user necessary for access control
+ * checks and authentications, such as what privileges this user has as well as what roles
+ * he/she belongs to.
+ *
+ * Every User object is owned by an AuthorizationManager. The AuthorizationManager is the only
+ * one that should construct, modify, or delete a User object. All other consumers of User must
+ * use only the const methods. The AuthorizationManager is responsible for maintaining the
+ * reference count on all User objects it gives out and must not mutate any User objects with
+ * a non-zero reference count (except to call invalidate()). Any consumer of a User object
+ * should check isInvalidated() before using it, and if it has been invalidated, it should
+ * return the object to the AuthorizationManager and fetch a new User object instance for this
+ * user from the AuthorizationManager.
+ */
+ class User {
+ MONGO_DISALLOW_COPYING(User);
+ public:
+ struct CredentialData {
+ std::string password;
+ };
+
+ explicit User(const UserName& name);
+ ~User();
+
+ /**
+ * Returns the user name for this user.
+ */
+ const UserName& getName() const;
+
+ /**
+ * Returns an iterator that can be used to get the list of roles this user belongs to.
+ */
+ const RoleNameIterator getRoles() const;
+
+ /**
+ * Gets the set of actions this user is allowed to perform on the given resource.
+ */
+ const ActionSet getActionsForResource(const std::string& resource) const;
+
+ /**
+ * Returns true if this copy of information about this user is still valid. If this returns
+ * false, this object should no longer be used and should be returned to the
+ * AuthorizationManager and a new User object for this user should be requested.
+ */
+ bool isValid() const;
+
+ /**
+ * This returns the reference count for this User. The AuthorizationManager should be the
+ * only caller of this.
+ */
+ uint32_t getRefCount() const;
+
+
+ // Mutators below. Mutation functions should *only* be called by the AuthorizationManager
+
+ /**
+ * Copies the contents of other into this User.
+ */
+ void copyFrom(const User& other);
+
+ /**
+ * Sets this user's authentication credentials.
+ */
+ void setCredentials(const CredentialData& credentials);
+
+ /**
+ * Adds the given role name to the list of roles of which this user is a member.
+ */
+ void addRole(const RoleName& role);
+
+ /**
+ * Adds the given role names to the list of roles that this user belongs to.
+ */
+ void addRoles(const std::vector<RoleName>& roles);
+
+ /**
+ * Adds the given privilege to the list of privileges this user is authorized for.
+ */
+ void addPrivilege(const Privilege& privilege);
+
+ /**
+ * Adds the given privileges to the list of privileges this user is authorized for.
+ */
+ void addPrivileges(const PrivilegeVector& privileges);
+
+ /**
+ * Marks this instance of the User object as invalid, most likely because information about
+ * the user has been updated and needs to be reloaded from the AuthorizationManager.
+ *
+ * This method should *only* be called by the AuthorizationManager.
+ */
+ void invalidate();
+
+ /**
+ * Increments the reference count for this User object, which records how many threads have
+ * a reference to it.
+ *
+ * This method should *only* be called by the AuthorizationManager.
+ */
+ void incrementRefCount();
+
+ /**
+ * Decrements the reference count for this User object, which records how many threads have
+ * a reference to it. Once the reference count goes to zero, the AuthorizationManager is
+ * allowed to destroy this instance.
+ *
+ * This method should *only* be called by the AuthorizationManager.
+ */
+ void decrementRefCount();
+
+
+ private:
+
+ UserName _name;
+
+ typedef unordered_map<std::string, Privilege> ResourcePrivilegeMap;
+
+ // Maps resource name to privilege on that resource
+ ResourcePrivilegeMap _privileges;
+
+ unordered_set<RoleName> _roles;
+
+ CredentialData _credentials;
+
+
+ // _refCount and _isInvalidated are modified exclusively by the AuthorizationManager
+ uint32_t _refCount;
+ AtomicUInt32 _isValid; // Using as a boolean
+
+ };
+
+} // namespace mongo