Class: Neo4j::Server::CypherAuthentication

Inherits:
Object
  • Object
show all
Defined in:
lib/neo4j-server/cypher_authentication.rb

Overview

Neo4j 2.2 has an authentication layer. This class provides methods for interacting with it.

Defined Under Namespace

Classes: InvalidPasswordError, MissingCredentialsError, PasswordChangeRequiredError

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (CypherAuthentication) initialize(url_string, session_connection = new_connection, params_hash = {})

same object used by the server for data, or a new one created specifically for auth tasks.

Parameters:

  • url_string (String)

    The server address with protocol and port.

  • session_connection (Faraday::Connection) (defaults to: new_connection)

    A Faraday::Connection object. This is either an existing object, likely the

  • params_hash (Hash) (defaults to: {})

    Faraday connection options. In particularly, we're looking for basic_auth creds.



15
16
17
18
19
# File 'lib/neo4j-server/cypher_authentication.rb', line 15

def initialize(url_string, session_connection = new_connection, params_hash = {})
  @url = url_string
  @connection = session_connection
  @params = params_hash
end

Instance Attribute Details

- (Object) connection (readonly)

Returns the value of attribute connection



9
10
11
# File 'lib/neo4j-server/cypher_authentication.rb', line 9

def connection
  @connection
end

- (Object) params (readonly)

Returns the value of attribute params



9
10
11
# File 'lib/neo4j-server/cypher_authentication.rb', line 9

def params
  @params
end

- (Object) token (readonly)

Returns the value of attribute token



9
10
11
# File 'lib/neo4j-server/cypher_authentication.rb', line 9

def token
  @token
end

- (Object) url (readonly)

Returns the value of attribute url



9
10
11
# File 'lib/neo4j-server/cypher_authentication.rb', line 9

def url
  @url
end

Instance Method Details

- (Object) add_auth_headers(token)

Stores an authentication token in the properly-formatted header. This does not do any checking that what it has been given is a token. Whatever param is given will be base64 encoded and used as the header.

Parameters:

  • token (String)

    The authentication token provided by the database.



94
95
96
97
# File 'lib/neo4j-server/cypher_authentication.rb', line 94

def add_auth_headers(token)
  @token = token
  connection.headers['Authorization'] = "Basic realm=\"Neo4j\" #{token_hash(token)}"
end

- (Faraday::Response) auth_attempt

Requests a token from the authentication endpoint using the given username and password.

Returns:

  • (Faraday::Response)

    The server's response, to be interpreted.



61
62
63
64
65
66
67
68
69
# File 'lib/neo4j-server/cypher_authentication.rb', line 61

def auth_attempt
  begin
    user = params[:basic_auth][:username]
    pass = params[:basic_auth][:password]
  rescue NoMethodError
    raise MissingCredentialsError, 'Neo4j authentication is enabled, username/password are required but missing'
  end
  connection.post("#{url}/authentication",  'username' => user, 'password' => pass)
end

- (String) authenticate

Uses the given username and password to obtain a token, then adds the token to the connection's parameters.

Returns:

  • (String)

    An access token provided by the server.



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/neo4j-server/cypher_authentication.rb', line 38

def authenticate
  auth_response = auth_connection("#{url}/authentication")
  auth_hash = if auth_response.body.empty?
                nil
              elsif auth_response.body.is_a?(String)
                JSON.parse(auth_response.body)['errors'][0]['code'] == 'Neo.ClientError.Security.AuthorizationFailed' ? auth_attempt : nil
              else
                auth_response
              end
  return nil if auth_hash.nil?
  add_auth_headers(token_or_error(auth_hash))
end

- (Object) basic_auth(username, password)

Set the username and password used to communicate with the server.



22
23
24
25
26
# File 'lib/neo4j-server/cypher_authentication.rb', line 22

def basic_auth(username, password)
  params[:basic_auth] ||= {}
  params[:basic_auth][:username] = username
  params[:basic_auth][:password] = password
end

- (Hash) change_password(old_password, new_password)

POSTs to the password change endpoint of the API. Does not invalidate tokens.

Parameters:

  • old_password (String)

    The current password.

  • new_password (String)

    The password you want to use.

Returns:

  • (Hash)

    The response from the server.



32
33
34
# File 'lib/neo4j-server/cypher_authentication.rb', line 32

def change_password(old_password, new_password)
  connection.post("#{url}/user/neo4j/password",  'password' => old_password, 'new_password' => new_password).body
end

- (Object) invalidate_token(current_password)

Parameters:

  • current_password (String)

    The current password used to connect to the database



87
88
89
# File 'lib/neo4j-server/cypher_authentication.rb', line 87

def invalidate_token(current_password)
  connection.post("#{url}/user/neo4j/authorization_token",  'password' => current_password).body
end

- (Object) reauthenticate(password)

Invalidates the existing token, which will invalidate all conncetions using this token, applies for a new token, adds this into the connection headers.

Parameters:

  • password (String)

    The current server password.



54
55
56
57
# File 'lib/neo4j-server/cypher_authentication.rb', line 54

def reauthenticate(password)
  invalidate_token(password)
  add_auth_headers(token_or_error(auth_attempt))
end

- (String) token_or_error(auth_response)

Takes a response object from the server and returns a token or fails with an error. TODO: more error states!

Parameters:

  • auth_response (Farday::Response)

    The response after attempting authentication

Returns:

  • (String)

    An authentication token.



75
76
77
78
79
80
81
82
83
# File 'lib/neo4j-server/cypher_authentication.rb', line 75

def token_or_error(auth_response)
  begin
    fail PasswordChangeRequiredError, "Server requires a password change, please visit #{url}" if auth_response.body['password_change_required']
    fail InvalidPasswordError, "Neo4j server responded with: #{auth_response.body['errors'][0]['message']}" if auth_response.status.to_i == 422
  rescue NoMethodError
    raise 'Unexpected auth response, please open an issue at https://github.com/neo4jrb/neo4j-core/issues'
  end
  auth_response.body['authorization_token']
end