Skip to content

Commit

Permalink
Add tests for basic, kerberos, custom, and sso auth (#237)
Browse files Browse the repository at this point in the history
Co-authored-by: Florent Biville <[email protected]>
  • Loading branch information
robsdedude and fbiville authored Oct 1, 2021
1 parent 21f7ec2 commit 1cdc9eb
Show file tree
Hide file tree
Showing 130 changed files with 950 additions and 262 deletions.
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

0 comments on commit 1cdc9eb

Please sign in to comment.