neo4j-core 3.1.0 → 3.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|