Skip to content

Commit d0d12c9

Browse files
authored
Merge pull request #122 from neo4j/1.1-unauthorized
Move Unauthorized into public API
2 parents 785f297 + 60e67d6 commit d0d12c9

File tree

5 files changed

+35
-15
lines changed

5 files changed

+35
-15
lines changed

neo4j/bolt/connection.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,7 @@ def on_success(self, metadata):
226226
connection.server = ServerInfo(address, version)
227227

228228
def on_failure(self, metadata):
229-
code = metadata.get("code")
230-
error = (Unauthorized if code == "Neo.ClientError.Security.Unauthorized" else
231-
ServiceUnavailable)
232-
raise error(metadata.get("message", "INIT failed"))
229+
raise ServiceUnavailable(metadata.get("message", "INIT failed"), metadata.get("code"))
233230

234231

235232
class Connection(object):
@@ -629,12 +626,11 @@ class ServiceUnavailable(Exception):
629626
""" Raised when no database service is available.
630627
"""
631628

629+
def __init__(self, message, code=None):
630+
super(ServiceUnavailable, self).__init__(message)
631+
self.code = code
632+
632633

633634
class ProtocolError(Exception):
634635
""" Raised when an unexpected or unsupported protocol event occurs.
635636
"""
636-
637-
638-
class Unauthorized(Exception):
639-
""" Raised when an action is not permitted.
640-
"""

neo4j/v1/bolt.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
fix_statement, fix_parameters, \
2828
CypherError, SessionExpired, SessionError
2929
from .routing import RoutingConnectionPool
30-
from .security import SecurityPlan
30+
from .security import SecurityPlan, Unauthorized
3131
from .summary import ResultSummary
3232
from .types import Record
3333

@@ -46,7 +46,12 @@ def __init__(self, uri, **config):
4646
Driver.__init__(self, pool)
4747

4848
def session(self, access_mode=None):
49-
return BoltSession(self.pool.acquire(self.address))
49+
try:
50+
return BoltSession(self.pool.acquire(self.address))
51+
except ServiceUnavailable as error:
52+
if error.code == "Neo.ClientError.Security.Unauthorized":
53+
raise Unauthorized(error.args[0])
54+
raise
5055

5156

5257
GraphDatabase.uri_schemes["bolt"] = DirectDriver

neo4j/v1/routing.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,10 @@ def fetch_routing_info(self, address):
178178
raise ServiceUnavailable("Server %r does not support routing" % (address,))
179179
else:
180180
raise ServiceUnavailable("Routing support broken on server %r" % (address,))
181-
except ServiceUnavailable:
181+
except ServiceUnavailable as error:
182+
if error.code == "Neo.ClientError.Security.Unauthorized":
183+
from neo4j.v1.security import Unauthorized
184+
raise Unauthorized(error.args[0])
182185
self.remove(address)
183186
return None
184187

@@ -264,7 +267,10 @@ def acquire_for_read(self):
264267
address = next(self.routing_table.readers)
265268
try:
266269
connection = self.acquire(address)
267-
except ServiceUnavailable:
270+
except ServiceUnavailable as error:
271+
if error.code == "Neo.ClientError.Security.Unauthorized":
272+
from neo4j.v1.security import Unauthorized
273+
raise Unauthorized(error.args[0])
268274
self.remove(address)
269275
else:
270276
return connection
@@ -279,7 +285,10 @@ def acquire_for_write(self):
279285
address = next(self.routing_table.writers)
280286
try:
281287
connection = self.acquire(address)
282-
except ServiceUnavailable:
288+
except ServiceUnavailable as error:
289+
if error.code == "Neo.ClientError.Security.Unauthorized":
290+
from neo4j.v1.security import Unauthorized
291+
raise Unauthorized(error.args[0])
283292
self.remove(address)
284293
else:
285294
return connection

neo4j/v1/security.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,8 @@ def _encryption_default():
126126
"so communications are not secure")
127127
_warned_about_insecure_default = True
128128
return ENCRYPTION_DEFAULT
129+
130+
131+
class Unauthorized(Exception):
132+
""" Raised when an action is not permitted.
133+
"""

test/test_driver.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
from neo4j.v1 import ServiceUnavailable, ProtocolError, READ_ACCESS, WRITE_ACCESS, \
2727
TRUST_ON_FIRST_USE, TRUST_CUSTOM_CA_SIGNED_CERTIFICATES, GraphDatabase, basic_auth, \
28-
custom_auth, SSL_AVAILABLE, SessionExpired, DirectDriver, RoutingDriver
28+
custom_auth, SSL_AVAILABLE, SessionExpired, DirectDriver, RoutingDriver, Unauthorized
2929
from test.util import ServerTestCase, StubCluster
3030

3131
BOLT_URI = "bolt://localhost:7687"
@@ -231,3 +231,8 @@ def test_custom_ca_not_implemented(self):
231231
with self.assertRaises(NotImplementedError):
232232
_ = GraphDatabase.driver(BOLT_URI, auth=AUTH_TOKEN,
233233
trust=TRUST_CUSTOM_CA_SIGNED_CERTIFICATES)
234+
235+
def test_should_fail_on_incorrect_password(self):
236+
with self.assertRaises(Unauthorized):
237+
with GraphDatabase.driver(BOLT_URI, auth=("neo4j", "wrong-password")) as driver:
238+
_ = driver.session()

0 commit comments

Comments
 (0)