Skip to content

PYTHON-1312 Remove Database.add_user and Database.remove_user #561

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ Breaking Changes in 4.0
:meth:`pymongo.database.Database.last_status`,
:meth:`pymongo.database.Database.previous_error`,
:meth:`pymongo.database.Database.reset_error_history`.
- Removed :meth:`pymongo.database.Database.add_user` and
:meth:`pymongo.database.Database.remove_user`.
- Removed :meth:`pymongo.collection.Collection.parallel_scan`.
- Removed :meth:`pymongo.collection.Collection.ensure_index`.
- Removed :meth:`pymongo.collection.Collection.reindex`.
Expand Down
33 changes: 33 additions & 0 deletions doc/migrate-to-pymongo4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,39 @@ can be changed to this::
names = client.list_collection_names()
non_system_names = client.list_collection_names(filter={"name": {"$regex": r"^(?!system\\.)"}})

Database.add_user is removed
............................

Removed :meth:`pymongo.database.Database.add_user` which was deprecated in
PyMongo 3.6. Use the `createUser command`_ or `updateUser command`_ instead.
To create a user::

db.command("createUser", "admin", pwd="password", roles=["dbAdmin"])

To create a read-only user::

db.command("createUser", "user", pwd="password", roles=["read"])

To change a password::

db.command("updateUser", "user", pwd="newpassword")

Or change roles::

db.command("updateUser", "user", roles=["readWrite"])

.. _createUser command: https://docs.mongodb.com/manual/reference/command/createUser/
.. _updateUser command: https://docs.mongodb.com/manual/reference/command/updateUser/

Database.remove_user is removed
...............................

Removed :meth:`pymongo.database.Database.remove_user` which was deprecated in
PyMongo 3.6. Use the `dropUser command`_ instead::

db.command("dropUser", "user")

.. _dropUser command: https://docs.mongodb.com/manual/reference/command/createUser/

Collection
----------
Expand Down
173 changes: 1 addition & 172 deletions pymongo/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@
from pymongo.collection import Collection
from pymongo.command_cursor import CommandCursor
from pymongo.errors import (CollectionInvalid,
ConfigurationError,
InvalidName,
OperationFailure)
InvalidName)
from pymongo.message import _first_batch
from pymongo.read_preferences import ReadPreference

Expand Down Expand Up @@ -982,175 +980,6 @@ def __next__(self):

next = __next__

def _default_role(self, read_only):
"""Return the default user role for this database."""
if self.name == "admin":
if read_only:
return "readAnyDatabase"
else:
return "root"
else:
if read_only:
return "read"
else:
return "dbOwner"

def _create_or_update_user(
self, create, name, password, read_only, session=None, **kwargs):
"""Use a command to create (if create=True) or modify a user.
"""
opts = {}
if read_only or (create and "roles" not in kwargs):
warnings.warn("Creating a user with the read_only option "
"or without roles is deprecated in MongoDB "
">= 2.6", DeprecationWarning)

opts["roles"] = [self._default_role(read_only)]

if read_only:
warnings.warn("The read_only option is deprecated in MongoDB "
">= 2.6, use 'roles' instead", DeprecationWarning)

if password is not None:
if "digestPassword" in kwargs:
raise ConfigurationError("The digestPassword option is not "
"supported via add_user. Please use "
"db.command('createUser', ...) "
"instead for this option.")
opts["pwd"] = password

# Don't send {} as writeConcern.
if self.write_concern.acknowledged and self.write_concern.document:
opts["writeConcern"] = self.write_concern.document
opts.update(kwargs)

if create:
command_name = "createUser"
else:
command_name = "updateUser"

self.command(command_name, name, session=session, **opts)

def add_user(self, name, password=None, read_only=None, session=None,
**kwargs):
"""**DEPRECATED**: Create user `name` with password `password`.

Add a new user with permissions for this :class:`Database`.

.. note:: Will change the password if user `name` already exists.

.. note:: add_user is deprecated and will be removed in PyMongo
4.0. Starting with MongoDB 2.6 user management is handled with four
database commands, createUser_, usersInfo_, updateUser_, and
dropUser_.

To create a user::

db.command("createUser", "admin", pwd="password", roles=["root"])

To create a read-only user::

db.command("createUser", "user", pwd="password", roles=["read"])

To change a password::

db.command("updateUser", "user", pwd="newpassword")

Or change roles::

db.command("updateUser", "user", roles=["readWrite"])

.. _createUser: https://docs.mongodb.com/manual/reference/command/createUser/
.. _usersInfo: https://docs.mongodb.com/manual/reference/command/usersInfo/
.. _updateUser: https://docs.mongodb.com/manual/reference/command/updateUser/
.. _dropUser: https://docs.mongodb.com/manual/reference/command/createUser/

.. warning:: Never create or modify users over an insecure network without
the use of TLS. See :doc:`/examples/tls` for more information.

:Parameters:
- `name`: the name of the user to create
- `password` (optional): the password of the user to create. Can not
be used with the ``userSource`` argument.
- `read_only` (optional): if ``True`` the user will be read only
- `**kwargs` (optional): optional fields for the user document
(e.g. ``userSource``, ``otherDBRoles``, or ``roles``). See
`<http://docs.mongodb.org/manual/reference/privilege-documents>`_
for more information.
- `session` (optional): a
:class:`~pymongo.client_session.ClientSession`.

.. versionchanged:: 3.7
Added support for SCRAM-SHA-256 users with MongoDB 4.0 and later.

.. versionchanged:: 3.6
Added ``session`` parameter. Deprecated add_user.

.. versionchanged:: 2.5
Added kwargs support for optional fields introduced in MongoDB 2.4

.. versionchanged:: 2.2
Added support for read only users
"""
warnings.warn("add_user is deprecated and will be removed in PyMongo "
"4.0. Use db.command with createUser or updateUser "
"instead", DeprecationWarning, stacklevel=2)
if not isinstance(name, str):
raise TypeError("name must be an instance of str")
if password is not None:
if not isinstance(password, str):
raise TypeError("password must be an instance of str")
if len(password) == 0:
raise ValueError("password can't be empty")
if read_only is not None:
read_only = common.validate_boolean('read_only', read_only)
if 'roles' in kwargs:
raise ConfigurationError("Can not use "
"read_only and roles together")

try:
uinfo = self.command("usersInfo", name, session=session)
# Create the user if not found in uinfo, otherwise update one.
self._create_or_update_user(
(not uinfo["users"]), name, password, read_only,
session=session, **kwargs)
except OperationFailure as exc:
# Unauthorized. Attempt to create the user in case of
# localhost exception.
if exc.code == 13:
self._create_or_update_user(
True, name, password, read_only, session=session, **kwargs)
else:
raise

def remove_user(self, name, session=None):
"""**DEPRECATED**: Remove user `name` from this :class:`Database`.

User `name` will no longer have permissions to access this
:class:`Database`.

.. note:: remove_user is deprecated and will be removed in PyMongo
4.0. Use the dropUser command instead::

db.command("dropUser", "user")

:Parameters:
- `name`: the name of the user to remove
- `session` (optional): a
:class:`~pymongo.client_session.ClientSession`.

.. versionchanged:: 3.6
Added ``session`` parameter. Deprecated remove_user.
"""
warnings.warn("remove_user is deprecated and will be removed in "
"PyMongo 4.0. Use db.command with dropUser "
"instead", DeprecationWarning, stacklevel=2)
cmd = SON([("dropUser", name)])
# Don't send {} as writeConcern.
if self.write_concern.acknowledged and self.write_concern.document:
cmd["writeConcern"] = self.write_concern.document
self.command(cmd, session=session)

def authenticate(self, name=None, password=None,
source=None, mechanism='DEFAULT', **kwargs):
"""**DEPRECATED**: Authenticate to use this database.
Expand Down
Loading