Skip to content

Support for custom auth-tokens #221

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 2 commits into from
Sep 8, 2016
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
58 changes: 58 additions & 0 deletions driver/src/main/java/org/neo4j/driver/v1/AuthTokens.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*/
package org.neo4j.driver.v1;

import java.util.Map;

import org.neo4j.driver.internal.security.InternalAuthToken;

import static org.neo4j.driver.v1.Values.parameters;
Expand Down Expand Up @@ -46,6 +48,62 @@ public static AuthToken basic( String username, String password )
"credentials", password ).asMap( Values.ofValue() ) );
}

/**
* The basic authentication scheme, using a username and a password.
* @param username this is the "principal", identifying who this token represents
* @param password this is the "credential", proving the identity of the user
* @param realm this is the "realm", specifies the authentication provider
* @return an authentication token that can be used to connect to Neo4j
* @see GraphDatabase#driver(String, AuthToken)
*/
public static AuthToken basic( String username, String password, String realm )
{
return new InternalAuthToken( parameters(
"scheme", "basic",
"principal", username,
"credentials", password,
"realm", realm).asMap( Values.ofValue() ) );
}


/**
* A custom authentication token used for doing custom authentication on the server side.
* @param principal this used to identify who this token represents
* @param credentials this is credentials authenticating the principal
* @param realm this is the "realm:, specifying the authentication provider.
* @param scheme this it the authentication scheme, specifying what kind of authentication that should be used
* @return an authentication token that can be used to connect to Neo4j
* * @see GraphDatabase#driver(String, AuthToken)
*/
public static AuthToken custom( String principal, String credentials, String realm, String scheme)
{
return new InternalAuthToken( parameters(
"scheme", scheme,
"principal", principal,
"credentials", credentials,
"realm", realm).asMap( Values.ofValue() ) );
}

/**
* A custom authentication token used for doing custom authentication on the server side.
* @param principal this used to identify who this token represents
* @param credentials this is credentials authenticating the principal
* @param realm this is the "realm:, specifying the authentication provider.
* @param scheme this it the authentication scheme, specifying what kind of authentication that shoud be used
* @param parameters extra parameters to be sent along the authentication provider.
* @return an authentication token that can be used to connect to Neo4j
* * @see GraphDatabase#driver(String, AuthToken)
*/
public static AuthToken custom( String principal, String credentials, String realm, String scheme, Map<String, Object> parameters)
{
return new InternalAuthToken( parameters(
"scheme", scheme,
"principal", principal,
"credentials", credentials,
"realm", realm,
"parameters", parameters).asMap( Values.ofValue() ) );
}

/**
* No authentication scheme. This will only work if authentication is disabled
* on the Neo4j Instance we are connecting to.
Expand Down
101 changes: 101 additions & 0 deletions driver/src/test/java/org/neo4j/driver/v1/AuthTokensTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/**
* Copyright (c) 2002-2016 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.neo4j.driver.v1;

import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

import org.neo4j.driver.internal.security.InternalAuthToken;
import org.neo4j.driver.internal.value.ListValue;
import org.neo4j.driver.internal.value.MapValue;
import org.neo4j.driver.internal.value.StringValue;

import static java.util.Arrays.asList;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
import static org.neo4j.driver.v1.AuthTokens.basic;
import static org.neo4j.driver.v1.AuthTokens.custom;
import static org.neo4j.driver.v1.Values.values;

public class AuthTokensTest
{

@Test
public void basicAuthWithoutRealm()
{
InternalAuthToken basic = (InternalAuthToken) basic( "foo", "bar" );

Map<String,Value> map = basic.toMap();

assertThat( map.size(), equalTo( 3 ) );
assertThat( map.get( "scheme" ), equalTo( (Value) new StringValue( "basic" ) ) );
assertThat( map.get( "principal" ), equalTo( (Value) new StringValue( "foo" ) ) );
assertThat( map.get( "credentials" ), equalTo( (Value) new StringValue( "bar" ) ) );
}

@Test
public void basicAuthWithRealm()
{
InternalAuthToken basic = (InternalAuthToken) basic( "foo", "bar", "baz" );

Map<String,Value> map = basic.toMap();

assertThat( map.size(), equalTo( 4 ) );
assertThat( map.get( "scheme" ), equalTo( (Value) new StringValue( "basic" ) ) );
assertThat( map.get( "principal" ), equalTo( (Value) new StringValue( "foo" ) ) );
assertThat( map.get( "credentials" ), equalTo( (Value) new StringValue( "bar" ) ) );
assertThat( map.get( "realm" ), equalTo( (Value) new StringValue( "baz" ) ) );
}

@Test
public void customAuthWithoutParameters()
{
InternalAuthToken basic = (InternalAuthToken) custom( "foo", "bar", "baz", "my_scheme" );

Map<String,Value> map = basic.toMap();

assertThat( map.size(), equalTo( 4 ) );
assertThat( map.get( "scheme" ), equalTo( (Value) new StringValue( "my_scheme" ) ) );
assertThat( map.get( "principal" ), equalTo( (Value) new StringValue( "foo" ) ) );
assertThat( map.get( "credentials" ), equalTo( (Value) new StringValue( "bar" ) ) );
assertThat( map.get( "realm" ), equalTo( (Value) new StringValue( "baz" ) ) );
}

@Test
public void customAuthParameters()
{
HashMap<String,Object> parameters = new HashMap<>();
parameters.put( "list", asList( 1, 2, 3 ) );
InternalAuthToken basic = (InternalAuthToken) custom( "foo", "bar", "baz", "my_scheme", parameters );


Map<String,Value> expectedParameters = new HashMap<>();
expectedParameters.put( "list", new ListValue( values( 1, 2, 3 ) ) );
Map<String,Value> map = basic.toMap();

assertThat( map.size(), equalTo( 5 ) );
assertThat( map.get( "scheme" ), equalTo( (Value) new StringValue( "my_scheme" ) ) );
assertThat( map.get( "principal" ), equalTo( (Value) new StringValue( "foo" ) ) );
assertThat( map.get( "credentials" ), equalTo( (Value) new StringValue( "bar" ) ) );
assertThat( map.get( "realm" ), equalTo( (Value) new StringValue( "baz" ) ) );
assertThat( map.get( "parameters" ), equalTo( (Value) new MapValue( expectedParameters ) ) );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;

import java.util.HashMap;

import org.neo4j.driver.internal.security.InternalAuthToken;
import org.neo4j.driver.v1.Driver;
import org.neo4j.driver.v1.GraphDatabase;
Expand All @@ -35,6 +37,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.neo4j.driver.v1.AuthTokens.basic;
import static org.neo4j.driver.v1.AuthTokens.custom;
import static org.neo4j.driver.v1.Values.ofValue;
import static org.neo4j.driver.v1.Values.parameters;

Expand Down Expand Up @@ -85,6 +88,59 @@ public void shouldGetHelpfulErrorOnInvalidCredentials() throws Throwable
}
}

@Test
public void shouldBeAbleToProvideRealmWithBasicAuth() throws Throwable
{
// Given
String password = "secret";
enableAuth( password );

// When & Then
try( Driver driver = GraphDatabase.driver( neo4j.uri(),
basic("neo4j", password, "native") );
Session session = driver.session() )
{
Value single = session.run( "CREATE () RETURN 1" ).single().get( 0 );
assertThat( single.asLong(), equalTo( 1L ) );
}
}

@Test
public void shouldBeAbleToConnectWithCustomToken() throws Throwable
{
// Given
String password = "secret";
enableAuth( password );

// When & Then
try( Driver driver = GraphDatabase.driver( neo4j.uri(),
custom("neo4j", password, "native", "basic" ) );
Session session = driver.session() )
{
Value single = session.run( "CREATE () RETURN 1" ).single().get( 0 );
assertThat( single.asLong(), equalTo( 1L ) );
}
}

@Test
public void shouldBeAbleToConnectWithCustomTokenWithAdditionalParameters() throws Throwable
{
// Given
String password = "secret";
enableAuth( password );
HashMap<String,Object> parameters = new HashMap<>();
parameters.put( "secret", 16 );

// When & Then
try( Driver driver = GraphDatabase.driver( neo4j.uri(),
custom("neo4j", password, "native", "basic", parameters ) );
Session session = driver.session() )
{
Value single = session.run( "CREATE () RETURN 1" ).single().get( 0 );
assertThat( single.asLong(), equalTo( 1L ) );
}
}

private void enableAuth( String password ) throws Exception
{
neo4j.restart( Neo4jSettings.TEST_SETTINGS
Expand Down