Skip to content

Commit 6384157

Browse files
committed
Merge pull request #128 from boggle/1.0-basic-auth
Draft Authentication API
2 parents 9d30dcc + 506829a commit 6384157

26 files changed

+475
-81
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* Copyright (c) 2002-2016 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver.internal;
20+
21+
import java.net.URI;
22+
23+
import org.neo4j.driver.internal.pool.InternalConnectionPool;
24+
import org.neo4j.driver.internal.spi.ConnectionPool;
25+
import org.neo4j.driver.v1.AuthToken;
26+
import org.neo4j.driver.v1.Config;
27+
import org.neo4j.driver.v1.Driver;
28+
import org.neo4j.driver.v1.Session;
29+
30+
public class InternalDriver implements Driver
31+
{
32+
private final ConnectionPool connections;
33+
private final URI url;
34+
private final Config config;
35+
36+
public InternalDriver( URI url, AuthToken authToken, Config config )
37+
{
38+
this.url = url;
39+
this.connections = new InternalConnectionPool( config, authToken );
40+
this.config = config;
41+
}
42+
43+
/**
44+
* Establish a session
45+
* @return a session that could be used to run {@link Session#run(String) a statement} or
46+
* {@link Session#beginTransaction() a transaction }.
47+
*/
48+
@Override
49+
public Session session()
50+
{
51+
return new InternalSession( connections.acquire( url ), config.logging().getLog( "session" ) );
52+
}
53+
54+
/**
55+
* Close all the resources assigned to this driver
56+
* @throws Exception any error that might happen when releasing all resources
57+
*/
58+
public void close() throws Exception
59+
{
60+
connections.close();
61+
}
62+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Copyright (c) 2002-2016 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver.internal.auth;
20+
21+
import java.util.Map;
22+
23+
import org.neo4j.driver.v1.Value;
24+
import org.neo4j.driver.v1.AuthToken;
25+
26+
/**
27+
* A simple common token for authentication schemes that easily convert to
28+
* an auth token map
29+
*/
30+
public class InternalAuthToken implements AuthToken
31+
{
32+
private final Map<String,Value> content;
33+
34+
public InternalAuthToken( Map<String,Value> content )
35+
{
36+
this.content = content;
37+
}
38+
39+
public Map<String, Value> toMap()
40+
{
41+
return content;
42+
}
43+
44+
@Override
45+
public boolean equals( Object o )
46+
{
47+
if ( this == o )
48+
{ return true; }
49+
if ( o == null || getClass() != o.getClass() )
50+
{ return false; }
51+
52+
InternalAuthToken that = (InternalAuthToken) o;
53+
54+
return content != null ? content.equals( that.content ) : that.content == null;
55+
56+
}
57+
58+
@Override
59+
public int hashCode()
60+
{
61+
return content != null ? content.hashCode() : 0;
62+
}
63+
}

driver/src/main/java/org/neo4j/driver/internal/connector/socket/LoggingResponseHandler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ public LoggingResponseHandler( Logger logger )
4040
}
4141

4242
@Override
43-
public void handleInitMessage( String clientNameAndVersion )
43+
public void handleInitMessage( String clientNameAndVersion, Map<String,Value> authToken )
4444
{
45-
super.handleInitMessage( clientNameAndVersion );
45+
super.handleInitMessage( clientNameAndVersion, authToken );
4646
logger.debug( "S: [INIT \"%s\"]", clientNameAndVersion );
4747
}
4848

driver/src/main/java/org/neo4j/driver/internal/connector/socket/SocketConnection.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ public SocketConnection( String host, int port, Config config )
6666
}
6767

6868
@Override
69-
public void init( String clientName )
69+
public void init( String clientName, Map<String,Value> authToken )
7070
{
71-
queueMessage( new InitMessage( clientName ), StreamCollector.NO_OP );
71+
queueMessage( new InitMessage( clientName, authToken ), StreamCollector.NO_OP );
7272
}
7373

7474
@Override

driver/src/main/java/org/neo4j/driver/internal/connector/socket/SocketConnector.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,16 @@
2121
import java.net.URI;
2222
import java.util.Collection;
2323
import java.util.Collections;
24+
import java.util.Map;
2425

2526
import org.neo4j.driver.internal.Version;
27+
import org.neo4j.driver.internal.auth.InternalAuthToken;
2628
import org.neo4j.driver.internal.spi.Connection;
2729
import org.neo4j.driver.internal.spi.Connector;
2830
import org.neo4j.driver.v1.Config;
31+
import org.neo4j.driver.v1.Value;
32+
import org.neo4j.driver.v1.AuthToken;
33+
import org.neo4j.driver.v1.AuthTokens;
2934
import org.neo4j.driver.v1.exceptions.ClientException;
3035

3136
public class SocketConnector implements Connector
@@ -40,11 +45,11 @@ public boolean supports( String scheme )
4045
}
4146

4247
@Override
43-
public Connection connect( URI sessionURI, Config config ) throws ClientException
48+
public Connection connect( URI sessionURI, Config config, AuthToken authToken ) throws ClientException
4449
{
4550
int port = sessionURI.getPort() == -1 ? DEFAULT_PORT : sessionURI.getPort();
4651
SocketConnection conn = new SocketConnection( sessionURI.getHost(), port, config );
47-
conn.init( "bolt-java-driver/" + Version.driverVersion() );
52+
conn.init( "bolt-java-driver/" + Version.driverVersion(), tokenAsMap( authToken ) );
4853
return conn;
4954
}
5055

@@ -53,4 +58,17 @@ public Collection<String> supportedSchemes()
5358
{
5459
return Collections.singletonList( SCHEME );
5560
}
61+
62+
private Map<String,Value> tokenAsMap( AuthToken token )
63+
{
64+
if( token instanceof InternalAuthToken )
65+
{
66+
return ((InternalAuthToken) token).toMap();
67+
}
68+
else
69+
{
70+
throw new ClientException( "Unknown authentication token, `" + token + "`. Please use one of the supported " +
71+
"tokens from `" + AuthTokens.class.getSimpleName() + "`." );
72+
}
73+
}
5674
}

driver/src/main/java/org/neo4j/driver/internal/connector/socket/SocketResponseHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ public void handlePullAllMessage()
198198
}
199199

200200
@Override
201-
public void handleInitMessage( String clientNameAndVersion )
201+
public void handleInitMessage( String clientNameAndVersion, Map<String,Value> authToken )
202202
{
203203

204204
}

driver/src/main/java/org/neo4j/driver/internal/messaging/InitMessage.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
package org.neo4j.driver.internal.messaging;
2020

2121
import java.io.IOException;
22+
import java.util.Map;
23+
24+
import org.neo4j.driver.v1.Value;
2225

2326
import static java.lang.String.format;
2427

@@ -30,16 +33,18 @@
3033
public class InitMessage implements Message
3134
{
3235
private final String clientNameAndVersion;
36+
private Map<String,Value> authToken;
3337

34-
public InitMessage( String clientNameAndVersion )
38+
public InitMessage( String clientNameAndVersion, Map<String,Value> authToken )
3539
{
3640
this.clientNameAndVersion = clientNameAndVersion;
41+
this.authToken = authToken;
3742
}
3843

3944
@Override
4045
public void dispatch( MessageHandler handler ) throws IOException
4146
{
42-
handler.handleInitMessage( clientNameAndVersion );
47+
handler.handleInitMessage( clientNameAndVersion, authToken );
4348
}
4449

4550
@Override

driver/src/main/java/org/neo4j/driver/internal/messaging/MessageHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
public interface MessageHandler
2727
{
2828
// Requests
29-
void handleInitMessage( String clientNameAndVersion ) throws IOException;
29+
void handleInitMessage( String clientNameAndVersion, Map<String,Value> authToken ) throws IOException;
3030

3131
void handleRunMessage( String statement, Map<String,Value> parameters ) throws IOException;
3232

driver/src/main/java/org/neo4j/driver/internal/messaging/PackStreamMessageFormatV1.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
import org.neo4j.driver.internal.InternalRelationship;
3535
import org.neo4j.driver.internal.connector.socket.ChunkedInput;
3636
import org.neo4j.driver.internal.connector.socket.ChunkedOutput;
37-
import org.neo4j.driver.internal.packstream.BufferedChannelOutput;
3837
import org.neo4j.driver.internal.packstream.PackInput;
3938
import org.neo4j.driver.internal.packstream.PackOutput;
4039
import org.neo4j.driver.internal.packstream.PackStream;
@@ -105,11 +104,6 @@ public static class Writer implements MessageFormat.Writer, MessageHandler
105104
private final PackStream.Packer packer;
106105
private final Runnable onMessageComplete;
107106

108-
public Writer()
109-
{
110-
this( new BufferedChannelOutput( 8192 ), new NoOpRunnable() );
111-
}
112-
113107
/**
114108
* @param output interface to write messages to
115109
* @param onMessageComplete invoked for each message, after it's done writing to the output
@@ -121,10 +115,11 @@ public Writer( PackOutput output, Runnable onMessageComplete )
121115
}
122116

123117
@Override
124-
public void handleInitMessage( String clientNameAndVersion ) throws IOException
118+
public void handleInitMessage( String clientNameAndVersion, Map<String,Value> authToken ) throws IOException
125119
{
126120
packer.packStructHeader( 1, MSG_INIT );
127121
packer.pack( clientNameAndVersion );
122+
packRawMap( authToken );
128123
onMessageComplete.run();
129124
}
130125

@@ -445,7 +440,7 @@ private void unpackResetMessage( MessageHandler handler ) throws IOException
445440

446441
private void unpackInitMessage( MessageHandler handler ) throws IOException
447442
{
448-
handler.handleInitMessage( unpacker.unpackString() );
443+
handler.handleInitMessage( unpacker.unpackString(), unpackMap() );
449444
onMessageComplete.run();
450445
}
451446

driver/src/main/java/org/neo4j/driver/internal/pool/InternalConnectionPool.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.neo4j.driver.internal.spi.Connector;
3434
import org.neo4j.driver.internal.util.Clock;
3535
import org.neo4j.driver.internal.util.Consumer;
36+
import org.neo4j.driver.v1.AuthToken;
3637
import org.neo4j.driver.v1.Config;
3738
import org.neo4j.driver.v1.exceptions.ClientException;
3839

@@ -65,6 +66,7 @@ public class InternalConnectionPool implements ConnectionPool
6566
*/
6667
private final ValidationStrategy<PooledConnection> connectionValidation;
6768

69+
private final AuthToken authToken;
6870
/**
6971
* Timeout in milliseconds if there are no available sessions.
7072
*/
@@ -73,13 +75,16 @@ public class InternalConnectionPool implements ConnectionPool
7375
private final Clock clock;
7476
private final Config config;
7577

76-
public InternalConnectionPool( Config config )
78+
public InternalConnectionPool( Config config, AuthToken authToken )
7779
{
78-
this( loadConnectors(), Clock.SYSTEM, config, Long.getLong( "neo4j.driver.acquireSessionTimeout", 30_000 ) );
80+
this( loadConnectors(), Clock.SYSTEM, config, authToken,
81+
Long.getLong( "neo4j.driver.acquireSessionTimeout", 30_000 ) );
7982
}
8083

81-
public InternalConnectionPool( Collection<Connector> conns, Clock clock, Config config, long acquireTimeout )
84+
public InternalConnectionPool( Collection<Connector> conns, Clock clock, Config config,
85+
AuthToken authToken, long acquireTimeout )
8286
{
87+
this.authToken = authToken;
8388
this.acquireSessionTimeout = acquireTimeout;
8489
this.config = config;
8590
this.clock = clock;
@@ -180,7 +185,7 @@ public PooledConnection allocate( Consumer<PooledConnection> release )
180185
"'" + uri.getScheme() + "' is not a supported transport (in '" +
181186
uri + "', available transports are: " + connectorSchemes() + "." );
182187
}
183-
Connection conn = connector.connect( uri, config );
188+
Connection conn = connector.connect( uri, config, authToken );
184189
return new PooledConnection( conn, release );
185190
}
186191

driver/src/main/java/org/neo4j/driver/internal/pool/PooledConnection.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ public PooledConnection( Connection delegate, Consumer<PooledConnection> release
4141
}
4242

4343
@Override
44-
public void init( String clientName )
44+
public void init( String clientName, Map<String,Value> authToken )
4545
{
4646
try
4747
{
48-
delegate.init( clientName );
48+
delegate.init( clientName, authToken );
4949
}
5050
catch( RuntimeException e )
5151
{

driver/src/main/java/org/neo4j/driver/internal/spi/Connection.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ public interface Connection extends AutoCloseable
3131
/**
3232
* Initialize the connection. This must be done before any other action is allowed.
3333
* @param clientName should be the driver name and version: "java-driver/1.0.0"
34+
* @param authToken
3435
*/
35-
void init( String clientName );
36+
void init( String clientName, Map<String,Value> authToken );
3637

3738
/**
3839
* Queue up a run action. The collector will value called with metadata about the stream that will become available

driver/src/main/java/org/neo4j/driver/internal/spi/Connector.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.net.URI;
2222
import java.util.Collection;
2323

24+
import org.neo4j.driver.v1.AuthToken;
2425
import org.neo4j.driver.v1.Config;
2526
import org.neo4j.driver.v1.exceptions.ClientException;
2627

@@ -43,9 +44,10 @@ public interface Connector
4344
*
4445
* @param sessionURL a URL identifying a remote session
4546
* @param config a configuration for this connection
47+
* @param authToken
4648
* @return a Connection object
4749
*/
48-
Connection connect( URI sessionURL, Config config ) throws ClientException;
50+
Connection connect( URI sessionURL, Config config, AuthToken authToken ) throws ClientException;
4951

5052
/** List names of supported schemes, used for error messages and similar signaling to end users. */
5153
Collection<String> supportedSchemes();

0 commit comments

Comments
 (0)