Skip to content
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
9 changes: 9 additions & 0 deletions nutkit/protocol/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ class Feature(Enum):
# This methods asserts that exactly one record in left in the result stream,
# else it will raise an exception.
API_RESULT_SINGLE = "Feature:API:Result.Single"
# The driver supports single-sign-on (SSO) by providing a bearer auth token
# API.
AUTH_BEARER = "Feature:Auth:Bearer"
# The driver supports custom authentication by providing a dedicated auth
# token API.
AUTH_CUSTOM = "Feature:Auth:Custom"
# The driver supports Kerberos authentication by providing a dedicated auth
# token API.
AUTH_KERBEROS = "Feature:Auth:Kerberos"

# === OPTIMIZATIONS ===
# On receiving Neo.ClientError.Security.AuthorizationExpired, the driver
Expand Down
25 changes: 19 additions & 6 deletions nutkit/protocol/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,28 @@ def __init__(self, uri, authToken, userAgent=None, resolverRegistered=False,

class AuthorizationToken:
""" Not a request but used in NewDriver request

The fields depend on the chosen scheme:
scheme == "basic"
- principal (str)
- credentials (str)
- realm (str, optional)
scheme == "kerberos"
- credentials (str)
scheme == "bearer"
- credentials (str)
further schemes should be handled with a multi-purpose auth API
(custom auth)
- principal (str, optional)
- credentials (str, optional)
- realm (str, optional)
- parameters (dict[str, Any], optional)
"""

def __init__(self, scheme="none", principal="",
credentials="", realm="", ticket=""):
def __init__(self, scheme, **kwargs):
self.scheme = scheme
self.principal = principal
self.credentials = credentials
self.realm = realm
self.ticket = ticket
for attr, value in kwargs.items():
setattr(self, attr, value)


class VerifyConnectivity:
Expand Down
2 changes: 1 addition & 1 deletion tests/neo4j/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def get_authorization():
"""
user = os.environ.get(env_neo4j_user, 'neo4j')
passw = os.environ.get(env_neo4j_pass, 'pass')
return AuthorizationToken(scheme="basic", principal=user, credentials=passw)
return AuthorizationToken("basic", principal=user, credentials=passw)


def get_neo4j_host_and_port():
Expand Down
6 changes: 3 additions & 3 deletions tests/neo4j/test_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def verifyConnectivity(self, auth_token):

@cluster_unsafe_test
def testErrorOnIncorrectCredentials(self):
auth_token = types.AuthorizationToken(scheme="basic",
auth_token = types.AuthorizationToken("basic",
principal="fake",
credentials="fake")
# TODO: Expand this to check errorType is AuthenticationError
Expand All @@ -48,7 +48,7 @@ def testErrorOnIncorrectCredentials(self):
@cluster_unsafe_test
def testSuccessOnProvideRealmWithBasicToken(self):
auth_token = types.AuthorizationToken(
scheme="basic",
"basic",
realm="native",
principal=os.environ.get(env_neo4j_user, "neo4j"),
credentials=os.environ.get(env_neo4j_pass, "pass"))
Expand All @@ -57,7 +57,7 @@ def testSuccessOnProvideRealmWithBasicToken(self):
@cluster_unsafe_test
def testSuccessOnBasicToken(self):
auth_token = types.AuthorizationToken(
scheme="basic",
"basic",
principal=os.environ.get(env_neo4j_user, "neo4j"),
credentials=os.environ.get(env_neo4j_pass, "pass"))
self.verifyConnectivity(auth_token)

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
!: BOLT #VERSION#

A: HELLO {"{}": "*"}
*: RESET
C: BEGIN {"mode": "r"}
S: FAILURE #ERROR#
<EXIT>
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ S: SUCCESS {"fields": ["n"]}
RECORD [1]
SUCCESS {"type": "r"}
C: COMMIT
S: FAILURE {"code": "Neo.ClientError.Security.AuthorizationExpired", "message": "Authorization expired"}
S: FAILURE #ERROR#
<EXIT>
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ S: SUCCESS {}
C: RUN "RETURN 1 as n" {} {}
S: SUCCESS {"fields": ["n"]}
C: PULL_ALL
S: FAILURE {"code": "Neo.ClientError.Security.AuthorizationExpired", "message": "Authorization expired"}
S: FAILURE #ERROR#
<EXIT>
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ S: SUCCESS {"fields": ["n"]}
RECORD [1]
SUCCESS {"type": "r"}
C: ROLLBACK
S: FAILURE {"code": "Neo.ClientError.Security.AuthorizationExpired", "message": "Authorization expired"}
S: FAILURE #ERROR#
<EXIT>
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ A: HELLO {"{}": "*"}
C: BEGIN {"mode": "r"}
S: SUCCESS {}
C: RUN "RETURN 1 as n" {} {}
S: FAILURE {"code": "Neo.ClientError.Security.AuthorizationExpired", "message": "Authorization expired"}
S: FAILURE #ERROR#
<EXIT>
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ A: HELLO {"{}": "*"}
C: RUN "RETURN 1 as n" {} {"mode": "r"}
S: SUCCESS {"fields": ["n"]}
C: PULL_ALL
S: FAILURE {"code": "Neo.ClientError.Security.AuthorizationExpired", "message": "Authorization expired"}
S: FAILURE #ERROR#
<EXIT>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
!: BOLT #VERSION#

A: HELLO {"{}": "*"}
*: RESET
C: BEGIN {"mode": "r", "db": "adb"}
S: FAILURE #ERROR#
S: <EXIT>
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ S: SUCCESS {"fields": ["n"]}
RECORD [1]
SUCCESS {"type": "r"}
C: COMMIT
S: FAILURE {"code": "Neo.ClientError.Security.AuthorizationExpired", "message": "Authorization expired"}
S: FAILURE #ERROR#
<EXIT>
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ S: SUCCESS {}
C: RUN "RETURN 1 as n" {} {}
S: SUCCESS {"fields": ["n"]}
C: PULL {"n": 1000}
S: FAILURE {"code": "Neo.ClientError.Security.AuthorizationExpired", "message": "Authorization expired"}
S: FAILURE #ERROR#
<EXIT>
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ S: SUCCESS {"fields": ["n"]}
RECORD [1]
SUCCESS {"type": "r"}
C: ROLLBACK
S: FAILURE {"code": "Neo.ClientError.Security.AuthorizationExpired", "message": "Authorization expired"}
S: FAILURE #ERROR#
<EXIT>
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
!: BOLT #VERSION#

A: HELLO {"{}": "*"}
*: RESET
C: BEGIN {"mode": "r", "db": "adb"}
S: SUCCESS {}
C: RUN "RETURN 1 as n" {} {}
S: FAILURE {"code": "Neo.ClientError.Security.AuthorizationExpired", "message": "Authorization expired"}
S: FAILURE #ERROR#
<EXIT>
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
!: BOLT #VERSION#

A: HELLO {"{}": "*"}
*: RESET
C: RUN "RETURN 1 as n" {} {"mode": "r", "db": "adb"}
S: SUCCESS {"fields": ["n"]}
C: PULL {"n": 1000}
S: FAILURE {"code": "Neo.ClientError.Security.AuthorizationExpired", "message": "Authorization expired"}
S: FAILURE #ERROR#
<EXIT>
13 changes: 13 additions & 0 deletions tests/stub/authorization/scripts/v4x3/scheme_basic.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 4.3

A: HELLO {"user_agent": "*", "scheme": "basic", "principal": "neo4j", "credentials": "pass", "[routing]": null, "[realm]": ""}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
13 changes: 13 additions & 0 deletions tests/stub/authorization/scripts/v4x3/scheme_basic_minimal.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 4.3

A: HELLO {"user_agent": "*", "scheme": "basic", "principal": "neo4j", "credentials": "pass"}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 4.3

A: HELLO {"user_agent": "*", "scheme": "basic", "principal": "neo4j", "credentials": "pass", "realm": "foobar", "[routing]": null}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 4.3

A: HELLO {"user_agent": "*", "scheme": "basic", "principal": "neo4j", "credentials": "pass", "realm": "foobar"}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
13 changes: 13 additions & 0 deletions tests/stub/authorization/scripts/v4x3/scheme_bearer.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 4.3

A: HELLO {"user_agent": "*", "scheme": "bearer", "credentials": "QmFuYW5hIQ==", "[principal]": "", "[routing]": null, "[realm]": ""}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
13 changes: 13 additions & 0 deletions tests/stub/authorization/scripts/v4x3/scheme_bearer_minimal.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 4.3

A: HELLO {"user_agent": "*", "scheme": "bearer", "credentials": "QmFuYW5hIQ=="}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
13 changes: 13 additions & 0 deletions tests/stub/authorization/scripts/v4x3/scheme_custom.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 4.3

A: HELLO {"user_agent": "*", "scheme": "wild-scheme", "principal": "I See Something", "credentials": "You Don't See!", "realm": "And it's blue.", "parameters": {"sky?": "no", "my eyes": 0.1, "da be dee da be daa?": true}, "[routing]": null}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
13 changes: 13 additions & 0 deletions tests/stub/authorization/scripts/v4x3/scheme_custom_empty.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 4.3

A: HELLO {"user_agent": "*", "scheme": "minimal-scheme", "principal": "", "[credentials]": "", "[realm]": "", "[parameters]": {}, "[routing]": null}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
!: BOLT 4.3

# Server versions pre 4.4 require empty principal field. So for backwards compatibility, we expect the driver to send it.
A: HELLO {"user_agent": "*", "scheme": "minimal-scheme", "principal": ""}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
13 changes: 13 additions & 0 deletions tests/stub/authorization/scripts/v4x3/scheme_custom_minimal.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 4.3

A: HELLO {"user_agent": "*", "scheme": "wild-scheme", "principal": "I See Something", "credentials": "You Don't See!", "realm": "And it's blue.", "parameters": {"sky?": "no", "my eyes": 0.1, "da be dee da be daa?": true}}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
14 changes: 14 additions & 0 deletions tests/stub/authorization/scripts/v4x3/scheme_kerberos.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
!: BOLT 4.3

# Server versions pre 4.4 require empty principal field. So for backwards compatibility, we expect the driver to send it.
A: HELLO {"user_agent": "*", "scheme": "kerberos", "principal": "", "credentials": "QmFuYW5hIQ==", "[routing]": null, "[realm]": ""}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
!: BOLT 4.3

# Server versions pre 4.4 require empty principal field. So for backwards compatibility, we expect the driver to send it.
A: HELLO {"user_agent": "*", "scheme": "kerberos", "principal": "", "credentials": "QmFuYW5hIQ=="}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
Loading