Skip to content

Commit edb07f7

Browse files
authored
Add support for impersonation (#599)
* Add support for impersonation * Add docs for impersonation * Add unit tests for impersonation * Acquire RT without impersonated user if possible This is an optimization saving a few bytes over the wire. When there is an explicit database configured for a session, there is no need to send the impersonated user along with the `ROUTE` request. The only difference this would make is that insufficient permissions would be noticed when fetching the RT instead of when performing any actual action on the session. Since routing is part of the global driver/pool operations and not coupled to sessions, doing it this way seems like the logical conclusion. * Only prefer initial router if RT got initialized w/o writers Previously, the driver would prefer the initial router for fetching a new RT whenever the current RT had no writers (left). However, if should check what the RT looked like when it was received.
1 parent 755b30d commit edb07f7

17 files changed

+454
-144
lines changed

docs/source/api.rst

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,12 @@ Name of the database to query.
486486

487487
.. Note::
488488

489-
The default database can be set on the Neo4j instance settings.
489+
The default database can be set on the Neo4j instance settings.
490+
491+
.. Note::
492+
It is recommended to always specify the database explicitly when possible.
493+
This allows the driver to work more efficiently, as it will not have to
494+
resolve the home database first.
490495

491496

492497
.. code-block:: python
@@ -499,6 +504,41 @@ Name of the database to query.
499504
:Default: ``neo4j.DEFAULT_DATABASE``
500505

501506

507+
.. _impersonated-user-ref:
508+
509+
``impersonated_user``
510+
---------------------
511+
Name of the user to impersonate.
512+
This means that all actions in the session will be executed in the security
513+
context of the impersonated user. For this, the user for which the
514+
:class:``Driver`` has been created needs to have the appropriate permissions.
515+
516+
:Type: ``str``, None
517+
518+
519+
.. py:data:: None
520+
:noindex:
521+
522+
Will not perform impersonation.
523+
524+
525+
.. Note::
526+
527+
The server or all servers of the cluster need to support impersonation when.
528+
Otherwise, the driver will raise :py:exc:`.ConfigurationError`
529+
as soon as it encounters a server that does not.
530+
531+
532+
.. code-block:: python
533+
534+
from neo4j import GraphDatabase
535+
driver = GraphDatabase.driver(uri, auth=(user, password))
536+
session = driver.session(impersonated_user="alice")
537+
538+
539+
:Default: ``None``
540+
541+
502542
.. _default-access-mode-ref:
503543

504544
``default_access_mode``

neo4j/__init__.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,9 @@ def supports_multi_db(self):
329329
:return: Returns true if the server or cluster the driver connects to supports multi-databases, otherwise false.
330330
:rtype: bool
331331
"""
332-
cx = self._pool.acquire(access_mode=READ_ACCESS, timeout=self._pool.workspace_config.connection_acquisition_timeout, database=self._pool.workspace_config.database)
333-
support = cx.supports_multiple_databases
334-
self._pool.release(cx)
335-
336-
return support
332+
with self.session() as session:
333+
session._connect(READ_ACCESS)
334+
return session._connection.supports_multiple_databases
337335

338336

339337
class BoltDriver(Direct, Driver):
@@ -447,6 +445,7 @@ def _verify_routing_connectivity(self):
447445
routing_info[ix] = self._pool.fetch_routing_info(
448446
address=table.routers[0],
449447
database=self._default_workspace_config.database,
448+
imp_user=self._default_workspace_config.impersonated_user,
450449
bookmarks=None,
451450
timeout=self._default_workspace_config
452451
.connection_acquisition_timeout

neo4j/conf.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,10 @@ class WorkspaceConfig(Config):
283283
#: Fetch Size
284284
fetch_size = 1000
285285

286+
#: User to impersonate
287+
impersonated_user = None
288+
# Note that you need appropriate permissions to do so.
289+
286290

287291
class SessionConfig(WorkspaceConfig):
288292
""" Session configuration.

0 commit comments

Comments
 (0)