neo4j-core 3.1.0 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/neo4j-core/version.rb +1 -1
- data/lib/neo4j-server/cypher_authentication.rb +34 -12
- data/lib/neo4j-server/cypher_node.rb +21 -24
- data/lib/neo4j-server/cypher_relationship.rb +10 -10
- data/lib/neo4j-server/cypher_session.rb +4 -4
- data/neo4j-core.gemspec +4 -5
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb8493440e6f8164e499189ebc58e95998b5bad1
|
4
|
+
data.tar.gz: 02678788be0642f10aa6781bdcb82fd11ab5fe97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82882d368b6ff790c061653f0cb68a2af37e328ef2ea948c507671108976d0a7ee60fac78653b6e254ca4a5d00c6cedf1bcda3bce15e038b446665042363fe5d
|
7
|
+
data.tar.gz: 76be0d527c6d6710eb3753fd370b747341efd3f099654447d9297a18d29bb01c330764183d206ef48fa59aab78ecdfa600cdb55879e0ad106a177e0188970035
|
data/lib/neo4j-core/version.rb
CHANGED
@@ -35,11 +35,16 @@ module Neo4j::Server
|
|
35
35
|
# Uses the given username and password to obtain a token, then adds the token to the connection's parameters.
|
36
36
|
# @return [String] An access token provided by the server.
|
37
37
|
def authenticate
|
38
|
-
auth_response =
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
auth_response = auth_connection("#{url}/authentication")
|
39
|
+
auth_hash = if auth_response.body.empty?
|
40
|
+
nil
|
41
|
+
elsif auth_response.body.is_a?(String)
|
42
|
+
JSON.parse(auth_response.body)['errors'][0]['code'] == 'Neo.ClientError.Security.AuthorizationFailed' ? auth_attempt : nil
|
43
|
+
else
|
44
|
+
auth_response
|
45
|
+
end
|
46
|
+
return nil if auth_hash.nil?
|
47
|
+
add_auth_headers(token_or_error(auth_hash))
|
43
48
|
end
|
44
49
|
|
45
50
|
# Invalidates the existing token, which will invalidate all conncetions using this token, applies for a new token, adds this into
|
@@ -47,21 +52,32 @@ module Neo4j::Server
|
|
47
52
|
# @param [String] password The current server password.
|
48
53
|
def reauthenticate(password)
|
49
54
|
invalidate_token(password)
|
50
|
-
add_auth_headers(
|
55
|
+
add_auth_headers(token_or_error(auth_attempt))
|
51
56
|
end
|
52
57
|
|
53
58
|
# Requests a token from the authentication endpoint using the given username and password.
|
54
|
-
# @return [
|
55
|
-
def
|
59
|
+
# @return [Faraday::Response] The server's response, to be interpreted.
|
60
|
+
def auth_attempt
|
56
61
|
begin
|
57
62
|
user = params[:basic_auth][:username]
|
58
63
|
pass = params[:basic_auth][:password]
|
59
64
|
rescue NoMethodError
|
60
65
|
raise MissingCredentialsError, 'Neo4j authentication is enabled, username/password are required but missing'
|
61
66
|
end
|
62
|
-
|
63
|
-
|
64
|
-
|
67
|
+
connection.post("#{url}/authentication", { 'username' => user, 'password' => pass })
|
68
|
+
end
|
69
|
+
|
70
|
+
# Takes a response object from the server and returns a token or fails with an error.
|
71
|
+
# Todo: more error states!
|
72
|
+
# @param [Farday::Response] auth_response The response after attempting authentication
|
73
|
+
# @return [String] An authentication token.
|
74
|
+
def token_or_error(auth_response)
|
75
|
+
begin
|
76
|
+
raise PasswordChangeRequiredError, "Server requires a password change, please visit #{url}" if auth_response.body['password_change_required']
|
77
|
+
raise InvalidPasswordError, "Neo4j server responded with: #{auth_response.body['errors'][0]['message']}" if auth_response.status.to_i == 422
|
78
|
+
rescue NoMethodError
|
79
|
+
raise 'Unexpected auth response, please open an issue at https://github.com/neo4jrb/neo4j-core/issues'
|
80
|
+
end
|
65
81
|
auth_response.body['authorization_token']
|
66
82
|
end
|
67
83
|
|
@@ -72,6 +88,7 @@ module Neo4j::Server
|
|
72
88
|
end
|
73
89
|
|
74
90
|
# Stores an authentication token in the properly-formatted header.
|
91
|
+
# 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.
|
75
92
|
# @param [String] token The authentication token provided by the database.
|
76
93
|
def add_auth_headers(token)
|
77
94
|
@token = token
|
@@ -80,6 +97,11 @@ module Neo4j::Server
|
|
80
97
|
|
81
98
|
private
|
82
99
|
|
100
|
+
# Makes testing easier, we can stub this method to simulate different responses
|
101
|
+
def auth_connection(url)
|
102
|
+
connection.get(url)
|
103
|
+
end
|
104
|
+
|
83
105
|
def self.new_connection
|
84
106
|
conn = Faraday.new do |b|
|
85
107
|
b.request :json
|
@@ -95,7 +117,7 @@ module Neo4j::Server
|
|
95
117
|
end
|
96
118
|
|
97
119
|
def token_hash(token)
|
98
|
-
Base64.strict_encode64(":#{token}")
|
120
|
+
::Base64.strict_encode64(":#{token}")
|
99
121
|
end
|
100
122
|
end
|
101
123
|
end
|
@@ -46,7 +46,7 @@ module Neo4j::Server
|
|
46
46
|
if @props
|
47
47
|
@props
|
48
48
|
else
|
49
|
-
hash = @session._query_entity_data("#{match_start} RETURN n")
|
49
|
+
hash = @session._query_entity_data("#{match_start} RETURN n", nil, neo_id: neo_id)
|
50
50
|
@props = Hash[hash['data'].map{ |k, v| [k.to_sym, v] }]
|
51
51
|
end
|
52
52
|
end
|
@@ -58,20 +58,20 @@ module Neo4j::Server
|
|
58
58
|
# (see Neo4j::Node#remove_property)
|
59
59
|
def remove_property(key)
|
60
60
|
refresh
|
61
|
-
@session._query_or_fail("#{match_start} REMOVE n.`#{key}`")
|
61
|
+
@session._query_or_fail("#{match_start} REMOVE n.`#{key}`", false, { neo_id: neo_id })
|
62
62
|
end
|
63
63
|
|
64
64
|
# (see Neo4j::Node#set_property)
|
65
65
|
def set_property(key,value)
|
66
66
|
refresh
|
67
|
-
@session._query_or_fail("#{match_start} SET n.`#{key}` = { value }", false, value: value)
|
67
|
+
@session._query_or_fail("#{match_start} SET n.`#{key}` = { value }", false, { value: value, neo_id: neo_id })
|
68
68
|
value
|
69
69
|
end
|
70
70
|
|
71
71
|
# (see Neo4j::Node#props=)
|
72
72
|
def props=(properties)
|
73
73
|
refresh
|
74
|
-
@session._query_or_fail("#{match_start} SET n = { props }", false, {props: properties})
|
74
|
+
@session._query_or_fail("#{match_start} SET n = { props }", false, { props: properties, neo_id: neo_id })
|
75
75
|
properties
|
76
76
|
end
|
77
77
|
|
@@ -80,7 +80,7 @@ module Neo4j::Server
|
|
80
80
|
q = "#{match_start} REMOVE " + properties.map do |k|
|
81
81
|
"n.`#{k}`"
|
82
82
|
end.join(', ')
|
83
|
-
@session._query_or_fail(q)
|
83
|
+
@session._query_or_fail(q, false, neo_id: neo_id)
|
84
84
|
end
|
85
85
|
|
86
86
|
# (see Neo4j::Node#update_props)
|
@@ -92,25 +92,19 @@ module Neo4j::Server
|
|
92
92
|
remove_properties(removed_keys) unless removed_keys.empty?
|
93
93
|
properties_to_set = properties.keys - removed_keys
|
94
94
|
return if properties_to_set.empty?
|
95
|
-
|
96
|
-
|
97
|
-
end.join(',')
|
98
|
-
@session._query_or_fail(q)
|
95
|
+
props_list = cypher_prop_list(properties)[:props].merge({ neo_id: neo_id })
|
96
|
+
@session._query_or_fail("#{match_start} SET #{cypher_properties(properties_to_set)}", false, props_list)
|
99
97
|
properties
|
100
98
|
end
|
101
99
|
|
102
100
|
# (see Neo4j::Node#get_property)
|
103
101
|
def get_property(key)
|
104
|
-
|
105
|
-
@props[key.to_sym]
|
106
|
-
else
|
107
|
-
@session._query_or_fail("#{match_start} RETURN n.`#{key}`", true)
|
108
|
-
end
|
102
|
+
@props ? @props[key.to_sym] : @session._query_or_fail("#{match_start} RETURN n.`#{key}`", true, neo_id: neo_id)
|
109
103
|
end
|
110
104
|
|
111
105
|
# (see Neo4j::Node#labels)
|
112
106
|
def labels
|
113
|
-
@labels ||= @session._query_or_fail("#{match_start} RETURN labels(n) as labels", true)
|
107
|
+
@labels ||= @session._query_or_fail("#{match_start} RETURN labels(n) as labels", true, neo_id: neo_id)
|
114
108
|
@labels.map(&:to_sym)
|
115
109
|
end
|
116
110
|
|
@@ -119,22 +113,21 @@ module Neo4j::Server
|
|
119
113
|
end
|
120
114
|
|
121
115
|
def add_label(*labels)
|
122
|
-
@session._query_or_fail("#{match_start} SET n #{_cypher_label_list(labels)}")
|
116
|
+
@session._query_or_fail("#{match_start} SET n #{_cypher_label_list(labels)}", false, neo_id: neo_id)
|
123
117
|
end
|
124
118
|
|
125
119
|
def remove_label(*labels)
|
126
|
-
@session._query_or_fail("#{match_start} REMOVE n #{_cypher_label_list(labels)}")
|
120
|
+
@session._query_or_fail("#{match_start} REMOVE n #{_cypher_label_list(labels)}", false, neo_id: neo_id)
|
127
121
|
end
|
128
122
|
|
129
123
|
def set_label(*label_names)
|
130
|
-
q = "#{match_start} #{remove_labels_if_needed} #{set_labels_if_needed(label_names)}"
|
131
|
-
@session._query_or_fail(q)
|
124
|
+
q = "#{match_start} #{remove_labels_if_needed} #{set_labels_if_needed(label_names)}"
|
125
|
+
@session._query_or_fail(q, false, neo_id: neo_id)
|
132
126
|
end
|
133
127
|
|
134
128
|
# (see Neo4j::Node#del)
|
135
129
|
def del
|
136
|
-
@session._query_or_fail("#{match_start} MATCH n-[r]-() DELETE r")
|
137
|
-
@session._query_or_fail("#{match_start} DELETE n")
|
130
|
+
@session._query_or_fail("#{match_start} OPTIONAL MATCH n-[r]-() DELETE n, r", false, neo_id: neo_id)
|
138
131
|
end
|
139
132
|
|
140
133
|
alias_method :delete, :del
|
@@ -142,7 +135,7 @@ module Neo4j::Server
|
|
142
135
|
|
143
136
|
# (see Neo4j::Node#exist?)
|
144
137
|
def exist?
|
145
|
-
@session._query("#{match_start} RETURN ID(n)").data.empty? ? false : true
|
138
|
+
@session._query("#{match_start} RETURN ID(n)", neo_id: neo_id).data.empty? ? false : true
|
146
139
|
end
|
147
140
|
|
148
141
|
# (see Neo4j::Node#node)
|
@@ -181,7 +174,7 @@ module Neo4j::Server
|
|
181
174
|
between_id = match[:between] ? "MATCH (p) WHERE ID(p) = #{match[:between].neo_id}" : ""
|
182
175
|
dir_func = to_dir[match[:dir] || :both]
|
183
176
|
cypher = "#{match_start} #{between_id} MATCH (n)#{dir_func.call(cypher_rel)}(p) RETURN #{returns}"
|
184
|
-
r = @session._query(cypher)
|
177
|
+
r = @session._query(cypher, neo_id: neo_id)
|
185
178
|
r.raise_error if r.error?
|
186
179
|
_map_result(r)
|
187
180
|
end
|
@@ -192,6 +185,10 @@ module Neo4j::Server
|
|
192
185
|
|
193
186
|
private
|
194
187
|
|
188
|
+
def cypher_properties(properties_to_set)
|
189
|
+
properties_to_set.map! { |k| "n.`#{k}` = {`#{k}`}"}.join(',')
|
190
|
+
end
|
191
|
+
|
195
192
|
def remove_labels_if_needed
|
196
193
|
if labels.empty?
|
197
194
|
""
|
@@ -215,7 +212,7 @@ module Neo4j::Server
|
|
215
212
|
end
|
216
213
|
|
217
214
|
def match_start(identifier = 'n')
|
218
|
-
"MATCH (#{identifier}) WHERE ID(#{identifier}) =
|
215
|
+
"MATCH (#{identifier}) WHERE ID(#{identifier}) = {neo_id}"
|
219
216
|
end
|
220
217
|
end
|
221
218
|
end
|
@@ -34,7 +34,7 @@ module Neo4j::Server
|
|
34
34
|
|
35
35
|
def load_resource
|
36
36
|
if resource_data.nil? || resource_data.empty?
|
37
|
-
@resource_data = @session._query_or_fail("#{match_start} RETURN n", true) # r.first_data
|
37
|
+
@resource_data = @session._query_or_fail("#{match_start} RETURN n", true, neo_id: neo_id) # r.first_data
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -69,15 +69,15 @@ module Neo4j::Server
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def get_property(key)
|
72
|
-
@session._query_or_fail("#{match_start} RETURN n.`#{key}`", true)
|
72
|
+
@session._query_or_fail("#{match_start} RETURN n.`#{key}`", true, neo_id: neo_id )
|
73
73
|
end
|
74
74
|
|
75
75
|
def set_property(key,value)
|
76
|
-
@session._query_or_fail("#{match_start} SET n.`#{key}` = {value}", false, {value: value})
|
76
|
+
@session._query_or_fail("#{match_start} SET n.`#{key}` = {value}", false, { value: value, neo_id: neo_id })
|
77
77
|
end
|
78
78
|
|
79
79
|
def remove_property(key)
|
80
|
-
@session._query_or_fail("#{match_start} REMOVE n.`#{key}`")
|
80
|
+
@session._query_or_fail("#{match_start} REMOVE n.`#{key}`", false, neo_id: neo_id)
|
81
81
|
end
|
82
82
|
|
83
83
|
# (see Neo4j::Relationship#props)
|
@@ -85,14 +85,14 @@ module Neo4j::Server
|
|
85
85
|
if @props
|
86
86
|
@props
|
87
87
|
else
|
88
|
-
hash = @session._query_entity_data("#{match_start} RETURN n")
|
88
|
+
hash = @session._query_entity_data("#{match_start} RETURN n", nil, neo_id: neo_id)
|
89
89
|
@props = Hash[hash['data'].map{ |k, v| [k.to_sym, v] }]
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
93
|
# (see Neo4j::Relationship#props=)
|
94
94
|
def props=(properties)
|
95
|
-
@session._query_or_fail("#{match_start} SET n = { props }", false, {props: properties})
|
95
|
+
@session._query_or_fail("#{match_start} SET n = { props }", false, { props: properties, neo_id: neo_id })
|
96
96
|
properties
|
97
97
|
end
|
98
98
|
|
@@ -102,7 +102,7 @@ module Neo4j::Server
|
|
102
102
|
q = "#{match_start} SET " + properties.keys.map do |k|
|
103
103
|
"n.`#{k}`= #{escape_value(properties[k])}"
|
104
104
|
end.join(',')
|
105
|
-
@session._query_or_fail(q)
|
105
|
+
@session._query_or_fail(q, false, neo_id: neo_id)
|
106
106
|
properties
|
107
107
|
end
|
108
108
|
|
@@ -111,13 +111,13 @@ module Neo4j::Server
|
|
111
111
|
end
|
112
112
|
|
113
113
|
def del
|
114
|
-
@session._query("#{match_start} DELETE n").raise_unless_response_code(200)
|
114
|
+
@session._query("#{match_start} DELETE n", neo_id: neo_id).raise_unless_response_code(200)
|
115
115
|
end
|
116
116
|
alias_method :delete, :del
|
117
117
|
alias_method :destroy, :del
|
118
118
|
|
119
119
|
def exist?
|
120
|
-
response = @session._query("#{match_start} RETURN n")
|
120
|
+
response = @session._query("#{match_start} RETURN n", neo_id: neo_id)
|
121
121
|
# binding.pry
|
122
122
|
(response.data.nil? || response.data.empty?) ? false : true
|
123
123
|
end
|
@@ -125,7 +125,7 @@ module Neo4j::Server
|
|
125
125
|
private
|
126
126
|
|
127
127
|
def match_start(identifier = 'n')
|
128
|
-
"MATCH (node)-[#{identifier}]-() WHERE ID(#{identifier}) =
|
128
|
+
"MATCH (node)-[#{identifier}]-() WHERE ID(#{identifier}) = {neo_id}"
|
129
129
|
end
|
130
130
|
end
|
131
131
|
end
|
@@ -56,7 +56,7 @@ module Neo4j::Server
|
|
56
56
|
|
57
57
|
def self.establish_session(root_data, connection, auth_obj)
|
58
58
|
data_url = root_data['data']
|
59
|
-
data_url << '/' unless data_url.end_with?('/')
|
59
|
+
data_url << '/' unless data_url.nil? || data_url.end_with?('/')
|
60
60
|
CypherSession.new(data_url, connection, auth_obj)
|
61
61
|
end
|
62
62
|
|
@@ -196,13 +196,13 @@ module Neo4j::Server
|
|
196
196
|
single_row ? response.first_data : response
|
197
197
|
end
|
198
198
|
|
199
|
-
def _query_entity_data(q, id=nil)
|
200
|
-
response = _query(q)
|
199
|
+
def _query_entity_data(q, id = nil, params = nil)
|
200
|
+
response = _query(q, params)
|
201
201
|
response.raise_error if response.error?
|
202
202
|
response.entity_data(id)
|
203
203
|
end
|
204
204
|
|
205
|
-
def _query(q, params=nil)
|
205
|
+
def _query(q, params = nil)
|
206
206
|
curr_tx = Neo4j::Transaction.current
|
207
207
|
if (curr_tx)
|
208
208
|
curr_tx._query(q, params)
|
data/neo4j-core.gemspec
CHANGED
@@ -6,13 +6,12 @@ require 'neo4j-core/version'
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "neo4j-core"
|
8
8
|
s.version = Neo4j::Core::VERSION
|
9
|
-
s.required_ruby_version = ">= 1.
|
9
|
+
s.required_ruby_version = ">= 1.9.3"
|
10
10
|
|
11
|
-
s.authors = "Andreas Ronge"
|
12
|
-
s.email = 'andreas.ronge@gmail.com'
|
11
|
+
s.authors = "Andreas Ronge, Chris Grigg, Brian Underwood"
|
12
|
+
s.email = 'andreas.ronge@gmail.com, chris@subvertallmedia.com, brian@brian-underwood.codes'
|
13
13
|
s.homepage = "https://github.com/neo4jrb/neo4j-core"
|
14
|
-
s.
|
15
|
-
s.summary = "A graph database for Ruby"
|
14
|
+
s.summary = "A basic library to work with the graph database Neo4j."
|
16
15
|
s.license = 'MIT'
|
17
16
|
|
18
17
|
s.description = <<-EOF
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: neo4j-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Andreas Ronge
|
7
|
+
- Andreas Ronge, Chris Grigg, Brian Underwood
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -138,7 +138,7 @@ dependencies:
|
|
138
138
|
version: '0'
|
139
139
|
description: |
|
140
140
|
Neo4j-core provides classes and methods to work with the graph database Neo4j.
|
141
|
-
email: andreas.ronge@gmail.com
|
141
|
+
email: andreas.ronge@gmail.com, chris@subvertallmedia.com, brian@brian-underwood.codes
|
142
142
|
executables: []
|
143
143
|
extensions: []
|
144
144
|
extra_rdoc_files:
|
@@ -208,17 +208,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
208
208
|
requirements:
|
209
209
|
- - ">="
|
210
210
|
- !ruby/object:Gem::Version
|
211
|
-
version: 1.
|
211
|
+
version: 1.9.3
|
212
212
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
213
213
|
requirements:
|
214
214
|
- - ">="
|
215
215
|
- !ruby/object:Gem::Version
|
216
216
|
version: '0'
|
217
217
|
requirements: []
|
218
|
-
rubyforge_project:
|
219
|
-
rubygems_version: 2.4.
|
218
|
+
rubyforge_project:
|
219
|
+
rubygems_version: 2.4.5
|
220
220
|
signing_key:
|
221
221
|
specification_version: 4
|
222
|
-
summary: A graph database
|
222
|
+
summary: A basic library to work with the graph database Neo4j.
|
223
223
|
test_files: []
|
224
224
|
has_rdoc: true
|