ruby-safenet 0.2.3 → 0.2.4
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/README.md +32 -27
- data/Rakefile +15 -0
- data/lib/safenet/version.rb +1 -1
- data/lib/safenet.rb +352 -225
- data/ruby-safenet.gemspec +0 -1
- metadata +3 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca8bf637841001a2a3edffcdaf9f7604f50e5714
|
4
|
+
data.tar.gz: 9595c12476853bd050a3a0caa576b018a2892bfc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c68964dfc3c4e5ce2c6c75d9aacbeba8ccf33d063a78b63e2c5a5f769a6c01ad67c2e6e64222f6debe4a99703b00069c60299485b78056f31d05e4a8547c1c2
|
7
|
+
data.tar.gz: c41cb857f2f15d3437ec7e9cc981b1f498ad3f154eaed7ea9c87cab9c4ac1fff6ba57c6053070819419042a5eea2066556f4e2d5e1b91758be19ff02a8abdf14
|
data/README.md
CHANGED
@@ -2,9 +2,11 @@
|
|
2
2
|
|
3
3
|
A simple SAFE API wrapper written in Ruby.
|
4
4
|
|
5
|
+
**Tested Aug 14, 2016. Working with SAFE version 0.5.**
|
6
|
+
|
5
7
|
## Installation
|
6
8
|
```
|
7
|
-
$ gem install safenet
|
9
|
+
$ gem install ruby-safenet
|
8
10
|
```
|
9
11
|
|
10
12
|
## Usage
|
@@ -13,11 +15,10 @@ A simple SAFE API wrapper written in Ruby.
|
|
13
15
|
require "safenet"
|
14
16
|
|
15
17
|
my_client = SafeNet::Client.new
|
16
|
-
my_client.nfs.
|
17
|
-
my_client.nfs.
|
18
|
-
my_client.nfs.update_file_content("/mydir/index.html", "Hello world!<br>I'm a webpage :D")
|
18
|
+
my_client.nfs.create_public_directory("/mydir")
|
19
|
+
my_client.nfs.create_file("/mydir/index.html", "Hello world!<br>I'm a webpage :D")
|
19
20
|
my_client.dns.register_service("my-wonderful-app", "www", "/mydir")
|
20
|
-
my_client.
|
21
|
+
my_client.nfs.get_file("/mydir/index.html")
|
21
22
|
|
22
23
|
# Then, open http://www.my-wonderful-app.safenet/
|
23
24
|
```
|
@@ -28,19 +29,18 @@ my_client = SafeNet::Client.new({
|
|
28
29
|
name: "Ruby Demo App",
|
29
30
|
version: "0.0.1",
|
30
31
|
vendor: "Vendor's Name",
|
31
|
-
id: "
|
32
|
+
id: "thevendor.demo",
|
32
33
|
})
|
33
34
|
```
|
34
35
|
|
35
36
|
*File Upload / Download:*
|
36
37
|
```ruby
|
37
38
|
# upload
|
38
|
-
my_client.nfs.
|
39
|
-
my_client.nfs.update_file_content("/mydir/dog.jpg", File.read("/home/daniel/Pictures/dog.jpg"))
|
39
|
+
my_client.nfs.create_file("/mydir/dog.jpg", File.read("/home/daniel/Pictures/dog.jpg"), content_type: "image/jpeg")
|
40
40
|
|
41
41
|
# download
|
42
42
|
File.open("/home/daniel/Pictures/dog-new.jpg", "w") do |file|
|
43
|
-
file.write(my_client.nfs.get_file("/mydir/dog.jpg"))
|
43
|
+
file.write(my_client.nfs.get_file("/mydir/dog.jpg")["body"])
|
44
44
|
end
|
45
45
|
```
|
46
46
|
|
@@ -57,7 +57,7 @@ All the information are stored in the Safe Network, through DNS/NFS sub-systems.
|
|
57
57
|
|
58
58
|
Example:
|
59
59
|
```ruby
|
60
|
-
my_client.sd.
|
60
|
+
my_client.sd.update(37267, 11, "Hi John") # 37267 = id, 11 = tag_type
|
61
61
|
my_client.sd.get(37267, 11)
|
62
62
|
my_client.sd.update(37267, 11, "Hello World!")
|
63
63
|
|
@@ -69,24 +69,29 @@ my_client.raw.get("861844d6704e8573fec34d967e20bcfef3d424cf48be04e6dc08f2bd58c72
|
|
69
69
|
Encryption and versioning are both not supported in this emulated version.
|
70
70
|
|
71
71
|
For more information see:
|
72
|
-
https://github.com/maidsafe/rfcs/blob/master/
|
72
|
+
https://github.com/maidsafe/rfcs/blob/master/text/0028-launcher-low-level-api/0028-launcher-low-level-api.md
|
73
73
|
|
74
74
|
## Supported methods:
|
75
75
|
|Module|Method|Arguments|Optional|Doc|
|
76
76
|
|------|------|---------|--------|---|
|
77
|
-
|sd|
|
78
|
-
|sd|
|
79
|
-
|
|
80
|
-
|nfs|
|
81
|
-
|nfs|
|
82
|
-
|nfs|
|
83
|
-
|nfs|
|
84
|
-
|nfs|
|
85
|
-
|nfs|
|
86
|
-
|nfs|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|dns|
|
92
|
-
|dns|
|
77
|
+
|sd|update|id (_int_), tag_type (_int_), contents (_string_\|_binary_)|||
|
78
|
+
|sd|get|id (_int_), tag_type (_int_)|||
|
79
|
+
|nfs|create_public_directory|dir_path (_string_)|root_path ("_app_" or "_drive_"), meta (_string_)|* _Alias to "create_directory"_|
|
80
|
+
|nfs|create_private_directory|dir_path (_string_)|root_path ("_app_" or "_drive_"), meta (_string_)|* _Alias to "create_directory"_|
|
81
|
+
|nfs|create_directory|dir_path (_string_)|is_private (_bool_), root_path ("_app_" or "_drive_"), meta (_string_)|https://maidsafe.readme.io/docs/nfs-create-directory|
|
82
|
+
|nfs|get_directory|dir_path (_string_)|root_path ("_app_" or "_drive_")|https://maidsafe.readme.io/docs/nfs-get-directory|
|
83
|
+
|nfs|rename_directory|dir_path (_string_), new_name (_string_)|root_path ("_app_" or "_drive_")|* _Alias to update_directory_|
|
84
|
+
|nfs|update_directory|dir_path (_string_)|root_path ("_app_" or "_drive_"), meta (_string_), name (_string_)|https://maidsafe.readme.io/docs/nfs-update-directory|
|
85
|
+
|nfs|delete_directory|dir_path (_string_)|root_path ("_app_" or "_drive_")|https://maidsafe.readme.io/docs/nfs-create-directory|
|
86
|
+
|nfs|create_file|file_path (_string_), contents (_string_ \| _binary_)|root_path ("_app_" or "_drive_"), meta (_string_), content_type (_string_)|https://maidsafe.readme.io/docs/nfsfile|
|
87
|
+
|nfs|get_file|file_path (_string_)|root_path ("_app_" or "_drive_"), offset (_int_), length (_int_), range (eg. "bytes 0-1000")|https://maidsafe.readme.io/docs/nfs-get-file|
|
88
|
+
|nfs|rename_file|file_path (_string_), new_name (_string_)|root_path ("_app_" or "_drive_"), meta (_string_)|* Alias to "update_file_meta"|
|
89
|
+
|nfs|update_file_meta|file_path (_string_)|root_path ("_app_" or "_drive_"), meta (_string_), name (_string_)|https://maidsafe.readme.io/docs/nfs-update-file-metadata|
|
90
|
+
|nfs|delete_file|file_path (_string_)|root_path ("_app_" or "_drive_")|https://maidsafe.readme.io/docs/nfs-delete-file|
|
91
|
+
|dns|create_long_name|long_name (_string_)||https://maidsafe.readme.io/docs/dns-create-long-name|
|
92
|
+
|dns|register_service|long_name (_string_), service_name (_string_), service_home_dir_path (_string_)||https://maidsafe.readme.io/docs/dns-register-service|
|
93
|
+
|dns|add_service|long_name (_string_), service_name (_string_), service_home_dir_path (_string_)||https://maidsafe.readme.io/docs/dns|
|
94
|
+
|dns|list_long_names||root_path ("_app_" or "_drive_")|https://maidsafe.readme.io/docs/dns-list-long-names|
|
95
|
+
|dns|list_services|long_name (_string_)||https://maidsafe.readme.io/docs/dns-list-services|
|
96
|
+
|dns|get_home_dir|long_name (_string_), service_name (_string_)||https://maidsafe.readme.io/docs/dns-get-home-dir|
|
97
|
+
|dns|get_file_unauth|long_name (_string_), service_name (_string_), file_path (_string_)||https://maidsafe.readme.io/docs/dns-get-file-unauth|
|
data/Rakefile
CHANGED
@@ -1 +1,16 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
module Bundler
|
4
|
+
class GemHelper
|
5
|
+
def install_gem(built_gem_path = nil, local = false)
|
6
|
+
conf_filename = File.join(File.expand_path('..', __FILE__), "conf.json")
|
7
|
+
File.open(conf_filename, "w") {}
|
8
|
+
File.chmod(0666, conf_filename)
|
9
|
+
|
10
|
+
built_gem_path ||= build_gem
|
11
|
+
out, _ = sh_with_code("gem install '#{built_gem_path}'#{" --local" if local}")
|
12
|
+
raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output" unless out[/Successfully installed/]
|
13
|
+
Bundler.ui.confirm "#{name} (#{version}) installed."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/safenet/version.rb
CHANGED
data/lib/safenet.rb
CHANGED
@@ -1,15 +1,9 @@
|
|
1
1
|
require "safenet/version"
|
2
2
|
require "net/http"
|
3
|
-
require "rbnacl"
|
4
3
|
require "base64"
|
5
4
|
require "json"
|
6
5
|
require "cgi" # CGI.escape method
|
7
6
|
|
8
|
-
# usage:
|
9
|
-
# my_client = SafeNet::Client.new(name: 'My App')
|
10
|
-
# my_client.nfs.file('x.txt')
|
11
|
-
# my_client.nfs.update_file_content('x.txt', 'Hello World!')
|
12
|
-
# my_client.nfs.get_file('x.txt')
|
13
7
|
module SafeNet
|
14
8
|
|
15
9
|
class Client
|
@@ -54,7 +48,6 @@ module SafeNet
|
|
54
48
|
|
55
49
|
def initialize(client_obj)
|
56
50
|
@client = client_obj
|
57
|
-
@keys = {}
|
58
51
|
@conf = {}
|
59
52
|
end
|
60
53
|
|
@@ -70,50 +63,6 @@ module SafeNet
|
|
70
63
|
@conf["token"]
|
71
64
|
end
|
72
65
|
|
73
|
-
def decrypt(message_base64)
|
74
|
-
keys = get_keys()
|
75
|
-
keys["secret_box"].decrypt(keys["symmetric_nonce"], Base64.strict_decode64(message_base64))
|
76
|
-
end
|
77
|
-
|
78
|
-
def encrypt(message)
|
79
|
-
keys = get_keys()
|
80
|
-
res = keys["secret_box"].encrypt(keys["symmetric_nonce"], message)
|
81
|
-
Base64.strict_encode64(res)
|
82
|
-
end
|
83
|
-
|
84
|
-
def invalidate
|
85
|
-
@keys = {}
|
86
|
-
end
|
87
|
-
|
88
|
-
private
|
89
|
-
|
90
|
-
def get_keys
|
91
|
-
# not loaded yet?
|
92
|
-
if @keys.empty?
|
93
|
-
get_valid_token() if @conf.empty?
|
94
|
-
|
95
|
-
# extract keys
|
96
|
-
cipher_text = Base64.strict_decode64(@conf["encryptedKey"])
|
97
|
-
nonce = Base64.strict_decode64(@conf["nonce"])
|
98
|
-
private_key = Base64.strict_decode64(@conf["privateKey"])
|
99
|
-
public_key = Base64.strict_decode64(@conf["publicKey"])
|
100
|
-
|
101
|
-
box = RbNaCl::Box.new(public_key, private_key)
|
102
|
-
data = box.decrypt(nonce, cipher_text)
|
103
|
-
|
104
|
-
# The first segment of the data will have the symmetric key
|
105
|
-
@keys["symmetric_key"] = data.slice(0, RbNaCl::SecretBox.key_bytes)
|
106
|
-
|
107
|
-
# The second segment of the data will have the nonce to be used
|
108
|
-
@keys["symmetric_nonce"] = data.slice(RbNaCl::SecretBox.key_bytes, RbNaCl::SecretBox.key_bytes)
|
109
|
-
|
110
|
-
# keep the box object in cache
|
111
|
-
@keys["secret_box"] = RbNaCl::SecretBox.new(@keys["symmetric_key"])
|
112
|
-
end
|
113
|
-
|
114
|
-
@keys
|
115
|
-
end
|
116
|
-
|
117
66
|
end
|
118
67
|
|
119
68
|
class Auth
|
@@ -122,36 +71,30 @@ module SafeNet
|
|
122
71
|
end
|
123
72
|
|
124
73
|
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
# from the SAFE Launcher to the application using ECDH Key Exchange.
|
128
|
-
# Applications will generate an asymmetric key pair and a nonce for ECDH Key
|
129
|
-
# Exchange with the SAFE Launcher.
|
74
|
+
# Any application that wants to access API endpoints that require authorised
|
75
|
+
# access must receive an authorisation token from SAFE Launcher.
|
130
76
|
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
# required permissions.
|
77
|
+
# Reading public data using the DNS API does not require an authorisation
|
78
|
+
# token. All other API endpoints require authorised access.
|
134
79
|
#
|
135
|
-
# The
|
136
|
-
#
|
137
|
-
#
|
138
|
-
#
|
139
|
-
#
|
80
|
+
# The application will initiate the authorisation request with information
|
81
|
+
# about the application itself and the required permissions. SAFE Launcher
|
82
|
+
# will then display a prompt to the user with the application information
|
83
|
+
# along with the requested permissions. Once the user authorises the
|
84
|
+
# request, the application will receive an authorisation token. If the user
|
85
|
+
# denies the request, the application will receive an unauthorised error
|
86
|
+
# response.
|
140
87
|
#
|
141
|
-
# Usage: my_client.auth()
|
88
|
+
# Usage: my_client.auth.auth(["SAFE_DRIVE_ACCESS"])
|
142
89
|
# Fail: nil
|
143
|
-
# Success: {token: "1222",
|
90
|
+
# Success: {token: "1222", "permissions": []}
|
144
91
|
#
|
145
92
|
# Reference: https://maidsafe.readme.io/docs/auth
|
146
93
|
#
|
147
|
-
def auth
|
94
|
+
def auth(permissions = [])
|
148
95
|
# entry point
|
149
96
|
url = "#{@client.app_info[:launcher_server]}auth"
|
150
97
|
|
151
|
-
# new random key
|
152
|
-
private_key = RbNaCl::PrivateKey.generate
|
153
|
-
nonce = RbNaCl::Random.random_bytes(24)
|
154
|
-
|
155
98
|
# payload
|
156
99
|
payload = {
|
157
100
|
app: {
|
@@ -160,9 +103,7 @@ module SafeNet
|
|
160
103
|
vendor: @client.app_info[:vendor],
|
161
104
|
id: @client.app_info[:id]
|
162
105
|
},
|
163
|
-
|
164
|
-
nonce: Base64.strict_encode64(nonce),
|
165
|
-
permissions: []
|
106
|
+
permissions: permissions
|
166
107
|
}
|
167
108
|
|
168
109
|
# api call
|
@@ -178,12 +119,7 @@ module SafeNet
|
|
178
119
|
|
179
120
|
# save it in conf.json
|
180
121
|
conf = response.dup
|
181
|
-
conf["nonce"] = Base64.strict_encode64(nonce)
|
182
|
-
conf["privateKey"] = Base64.strict_encode64(private_key)
|
183
122
|
File.open(@client.app_info[:conf_path], "w") { |f| f << JSON.pretty_generate(conf) }
|
184
|
-
|
185
|
-
# invalidates @keys
|
186
|
-
@client.key_helper.invalidate()
|
187
123
|
else
|
188
124
|
# puts "ERROR #{res.code}: #{res.message}"
|
189
125
|
response = nil
|
@@ -195,10 +131,10 @@ module SafeNet
|
|
195
131
|
|
196
132
|
|
197
133
|
#
|
198
|
-
#
|
199
|
-
#
|
134
|
+
# Check whether the authorisation token obtained from SAFE Launcher is still
|
135
|
+
# valid.
|
200
136
|
#
|
201
|
-
# Usage:
|
137
|
+
# Usage: my_client.auth.is_token_valid()
|
202
138
|
# Fail: false
|
203
139
|
# Success: true
|
204
140
|
#
|
@@ -220,9 +156,9 @@ module SafeNet
|
|
220
156
|
|
221
157
|
|
222
158
|
#
|
223
|
-
#
|
159
|
+
# Revoke the authorisation token obtained from SAFE Launcher.
|
224
160
|
#
|
225
|
-
# Usage:
|
161
|
+
# Usage: my_client.auth.revoke_token()
|
226
162
|
# Fail: false
|
227
163
|
# Success: true
|
228
164
|
#
|
@@ -250,198 +186,333 @@ module SafeNet
|
|
250
186
|
end
|
251
187
|
|
252
188
|
#
|
253
|
-
# Create a directory
|
189
|
+
# Create a public or private directory either in the application's root
|
190
|
+
# directory or in SAFE Drive.
|
254
191
|
# Only authorised requests can create a directory.
|
255
192
|
#
|
256
|
-
# Usage:
|
193
|
+
# Usage: my_client.nfs.create_directory("/photos")
|
194
|
+
# Adv.Usage: my_client.nfs.create_directory("/photos", meta: "some meta", root_path: 'drive', is_private: true)
|
195
|
+
# Fail: {"errorCode"=>-505, "description"=>"NfsError::FileAlreadyExistsWithSameName"}
|
196
|
+
# Success: true
|
197
|
+
#
|
198
|
+
# Reference: https://maidsafe.readme.io/docs/nfs-create-directory
|
199
|
+
#
|
200
|
+
def create_directory(dir_path, options = {})
|
201
|
+
# Default values
|
202
|
+
options[:root_path] = 'app' if ! options.has_key?(:root_path)
|
203
|
+
options[:is_private] = true if ! options.has_key?(:is_private)
|
204
|
+
|
205
|
+
# Entry point
|
206
|
+
url = "#{@client.app_info[:launcher_server]}nfs/directory/#{options[:root_path]}/#{CGI.escape(dir_path)}"
|
207
|
+
|
208
|
+
# Payload
|
209
|
+
payload = {
|
210
|
+
isPrivate: options[:is_private],
|
211
|
+
}
|
212
|
+
|
213
|
+
# Optional
|
214
|
+
payload["metadata"] = Base64.strict_encode64(options[:meta]) if options.has_key?(:meta)
|
215
|
+
|
216
|
+
# API call
|
217
|
+
uri = URI(url)
|
218
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
219
|
+
req = Net::HTTP::Post.new(uri.path, {
|
220
|
+
'Authorization' => "Bearer #{@client.key_helper.get_valid_token()}",
|
221
|
+
'Content-Type' => 'application/json'
|
222
|
+
})
|
223
|
+
req.body = payload.to_json
|
224
|
+
res = http.request(req)
|
225
|
+
res.code == "200" ? true : JSON.parse(res.body)
|
226
|
+
end
|
227
|
+
|
228
|
+
# Alias
|
229
|
+
def create_public_directory(dir_path, options = {})
|
230
|
+
options[:is_private] = false
|
231
|
+
self.create_directory(dir_path, options)
|
232
|
+
end
|
233
|
+
|
234
|
+
# Alias
|
235
|
+
def create_private_directory(dir_path, options = {})
|
236
|
+
options[:is_private] = true
|
237
|
+
self.create_directory(dir_path, options)
|
238
|
+
end
|
239
|
+
|
240
|
+
#
|
241
|
+
# Fetch a directory.
|
242
|
+
# Only authorised requests can invoke this API.
|
243
|
+
#
|
244
|
+
# Usage: my_client.nfs.get_directory("/photos", root_path: 'drive')
|
257
245
|
# Fail: {"errorCode"=>-1502, "description"=>"FfiError::PathNotFound"}
|
258
|
-
# Success: {"info"=> {"name"=> "
|
246
|
+
# Success: {"info"=> {"name"=> "my_dir", ...}, ...}
|
259
247
|
#
|
260
248
|
# Reference: https://maidsafe.readme.io/docs/nfs-get-directory
|
261
249
|
#
|
262
250
|
def get_directory(dir_path, options = {})
|
263
|
-
#
|
264
|
-
options[:
|
251
|
+
# Default values
|
252
|
+
options[:root_path] = 'app' if ! options.has_key?(:root_path)
|
265
253
|
|
266
|
-
#
|
267
|
-
url = "#{@client.app_info[:launcher_server]}nfs/directory/#{CGI.escape(dir_path)}
|
254
|
+
# Entry point
|
255
|
+
url = "#{@client.app_info[:launcher_server]}nfs/directory/#{options[:root_path]}/#{CGI.escape(dir_path)}"
|
268
256
|
|
269
|
-
#
|
257
|
+
# API call
|
270
258
|
uri = URI(url)
|
271
259
|
http = Net::HTTP.new(uri.host, uri.port)
|
272
260
|
req = Net::HTTP::Get.new(uri.path, {
|
273
261
|
'Authorization' => "Bearer #{@client.key_helper.get_valid_token()}",
|
274
262
|
})
|
275
263
|
res = http.request(req)
|
276
|
-
JSON.parse(
|
264
|
+
JSON.parse(res.body)
|
277
265
|
end
|
278
266
|
|
279
267
|
|
280
268
|
#
|
281
|
-
#
|
282
|
-
# Only authorised requests can invoke
|
269
|
+
# Rename a directory and (optionally) update its metadata.
|
270
|
+
# Only authorised requests can invoke this API.
|
283
271
|
#
|
284
|
-
#
|
285
|
-
#
|
272
|
+
# Rename: my_client.nfs.update_directory("/photos", name: "pics")
|
273
|
+
# Change meta: my_client.nfs.update_directory("/photos", meta: "new meta")
|
286
274
|
# Fail: {"errorCode"=>-505, "description"=>"NfsError::FileAlreadyExistsWithSameName"}
|
287
275
|
# Success: true
|
288
276
|
#
|
289
|
-
# Reference: https://maidsafe.readme.io/docs/
|
277
|
+
# Reference: https://maidsafe.readme.io/docs/nfs-update-directory
|
290
278
|
#
|
291
|
-
def
|
292
|
-
|
279
|
+
def update_directory(dir_path, options = {})
|
280
|
+
# Default values
|
281
|
+
options[:root_path] = 'app' if ! options.has_key?(:root_path)
|
293
282
|
|
294
|
-
#
|
295
|
-
options[:
|
296
|
-
options[:is_versioned] = false if ! options.has_key?(:is_versioned)
|
297
|
-
options[:is_path_shared] = false if ! options.has_key?(:is_path_shared)
|
283
|
+
# Entry point
|
284
|
+
url = "#{@client.app_info[:launcher_server]}nfs/directory/#{options[:root_path]}/#{CGI.escape(dir_path)}"
|
298
285
|
|
299
|
-
# payload
|
300
|
-
payload = {
|
301
|
-
|
302
|
-
|
303
|
-
isVersioned: options[:is_versioned],
|
304
|
-
isPathShared: options[:is_path_shared]
|
305
|
-
}
|
306
|
-
|
307
|
-
# optional
|
308
|
-
payload["metadata"] = Base64.strict_encode64(options[:metadata]) if options.has_key?(:metadata)
|
286
|
+
# Optional payload
|
287
|
+
payload = {}
|
288
|
+
payload["name"] = CGI.escape(options[:name]) if options.has_key?(:name)
|
289
|
+
payload["metadata"] = Base64.strict_encode64(options[:meta]) if options.has_key?(:meta)
|
309
290
|
|
310
|
-
#
|
291
|
+
# API call
|
311
292
|
uri = URI(url)
|
312
293
|
http = Net::HTTP.new(uri.host, uri.port)
|
313
|
-
req = Net::HTTP::
|
294
|
+
req = Net::HTTP::Put.new(uri.path, {
|
314
295
|
'Authorization' => "Bearer #{@client.key_helper.get_valid_token()}",
|
315
|
-
'Content-Type' => '
|
296
|
+
'Content-Type' => 'application/json'
|
316
297
|
})
|
317
|
-
req.body =
|
298
|
+
req.body = payload.to_json
|
318
299
|
res = http.request(req)
|
319
|
-
res.code == "200" ? true : JSON.parse(
|
300
|
+
res.code == "200" ? true : JSON.parse(res.body)
|
320
301
|
end
|
321
302
|
|
303
|
+
# Alias
|
304
|
+
def rename_directory(dir_path, new_name, options = {})
|
305
|
+
options[:name] = new_name
|
306
|
+
self.update_directory(dir_path, options)
|
307
|
+
end
|
322
308
|
|
323
309
|
#
|
324
|
-
#
|
325
|
-
# Only authorised requests can
|
310
|
+
# Delete a directory.
|
311
|
+
# Only authorised requests can invoke this API.
|
326
312
|
#
|
327
|
-
#
|
328
|
-
#
|
313
|
+
# Rename: my_client.nfs.delete_directory("/photos")
|
314
|
+
# Change meta: my_client.nfs.delete_directory("/photos", root_path: "app")
|
329
315
|
# Fail: {"errorCode"=>-505, "description"=>"NfsError::FileAlreadyExistsWithSameName"}
|
330
316
|
# Success: true
|
331
317
|
#
|
332
|
-
# Reference: https://maidsafe.readme.io/docs/nfs-
|
318
|
+
# Reference: https://maidsafe.readme.io/docs/nfs-delete-directory
|
333
319
|
#
|
334
|
-
def
|
335
|
-
#
|
336
|
-
|
320
|
+
def delete_directory(dir_path, options = {})
|
321
|
+
# Default values
|
322
|
+
options[:root_path] = 'app' if ! options.has_key?(:root_path)
|
337
323
|
|
338
|
-
#
|
339
|
-
options[:
|
340
|
-
options[:is_versioned] = false if ! options.has_key?(:is_versioned)
|
341
|
-
options[:is_path_shared] = false if ! options.has_key?(:is_path_shared)
|
324
|
+
# Entry point
|
325
|
+
url = "#{@client.app_info[:launcher_server]}nfs/directory/#{options[:root_path]}/#{CGI.escape(dir_path)}"
|
342
326
|
|
343
|
-
#
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
327
|
+
# API call
|
328
|
+
uri = URI(url)
|
329
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
330
|
+
req = Net::HTTP::Delete.new(uri.path, {
|
331
|
+
'Authorization' => "Bearer #{@client.key_helper.get_valid_token()}",
|
332
|
+
})
|
333
|
+
res = http.request(req)
|
334
|
+
res.code == "200" ? true : JSON.parse(res.body)
|
335
|
+
end
|
350
336
|
|
351
|
-
# optional
|
352
|
-
payload["metadata"] = Base64.strict_encode64(options[:metadata]) if options.has_key?(:metadata)
|
353
337
|
|
354
|
-
|
338
|
+
#
|
339
|
+
# Create a file.
|
340
|
+
# Only authorised requests can invoke the API.
|
341
|
+
#
|
342
|
+
# Usage: my_client.nfs.create_file("/docs/hello.txt", "Hello World!")
|
343
|
+
# Adv.Usage: my_client.nfs.create_file("/docs/hello.txt", meta: "some meta", root_path: "app", content_type: "text/plain")
|
344
|
+
# Fail: {"errorCode"=>-505, "description"=>"NfsError::FileAlreadyExistsWithSameName"}
|
345
|
+
# Success: true
|
346
|
+
#
|
347
|
+
# Reference: https://maidsafe.readme.io/docs/nfsfile
|
348
|
+
#
|
349
|
+
def create_file(file_path, contents, options = {})
|
350
|
+
# Default values
|
351
|
+
options[:root_path] = 'app' if ! options.has_key?(:root_path)
|
352
|
+
contents ||= ""
|
353
|
+
|
354
|
+
# Entry point
|
355
|
+
url = "#{@client.app_info[:launcher_server]}nfs/file/#{options[:root_path]}/#{CGI.escape(file_path)}"
|
356
|
+
|
357
|
+
# API call
|
355
358
|
uri = URI(url)
|
356
359
|
http = Net::HTTP.new(uri.host, uri.port)
|
357
|
-
|
360
|
+
headers = {
|
358
361
|
'Authorization' => "Bearer #{@client.key_helper.get_valid_token()}",
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
+
}
|
363
|
+
headers["Metadata"] = Base64.strict_encode64(options[:meta]) if options.has_key?(:meta)
|
364
|
+
headers["Content-Type"] = options[:content_type] || 'text/plain'
|
365
|
+
headers["Content-Length"] = contents.size.to_s
|
366
|
+
req = Net::HTTP::Post.new(uri.path, headers)
|
367
|
+
req.body = contents
|
362
368
|
res = http.request(req)
|
363
|
-
res.code == "200" ? true : JSON.parse(
|
369
|
+
res.code == "200" ? true : JSON.parse(res.body)
|
364
370
|
end
|
365
371
|
|
366
372
|
|
367
|
-
#
|
368
|
-
|
369
|
-
|
370
|
-
|
373
|
+
#
|
374
|
+
# Fetch the metadata of a file.
|
375
|
+
# Only authorised requests can invoke the API.
|
376
|
+
#
|
377
|
+
# Usage: my_client.nfs.get_file_meta("/docs/hello.txt")
|
378
|
+
# Adv.Usage: my_client.nfs.get_file_meta("/docs/hello.txt", root_path: "app")
|
379
|
+
# Fail: {"errorCode"=>-505, "description"=>"NfsError::FileAlreadyExistsWithSameName"}
|
380
|
+
# Success:
|
381
|
+
#
|
382
|
+
# Reference: https://maidsafe.readme.io/docs/nfs-get-file-metadata
|
383
|
+
#
|
384
|
+
def get_file_meta(file_path, options = {})
|
385
|
+
# Default values
|
386
|
+
options[:root_path] = 'app' if ! options.has_key?(:root_path)
|
371
387
|
|
372
|
-
#
|
373
|
-
url = "#{@client.app_info[:launcher_server]}nfs/
|
388
|
+
# Entry point
|
389
|
+
url = "#{@client.app_info[:launcher_server]}nfs/file/#{options[:root_path]}/#{CGI.escape(file_path)}"
|
374
390
|
|
375
|
-
#
|
391
|
+
# API call
|
376
392
|
uri = URI(url)
|
377
393
|
http = Net::HTTP.new(uri.host, uri.port)
|
378
|
-
|
394
|
+
headers = {
|
379
395
|
'Authorization' => "Bearer #{@client.key_helper.get_valid_token()}",
|
380
|
-
}
|
396
|
+
}
|
397
|
+
req = Net::HTTP::Head.new(uri.path, headers)
|
381
398
|
res = http.request(req)
|
382
|
-
|
399
|
+
res_headers = {}
|
400
|
+
res.response.each_header {|k,v| res_headers[k] = v}
|
401
|
+
res_headers["metadata"] = Base64.strict_decode64(res_headers["metadata"]) if res_headers.has_key?("metadata")
|
402
|
+
res.code == "200" ? {"headers" => res_headers, "body" => res.body} : JSON.parse(res.body)
|
383
403
|
end
|
384
404
|
|
385
|
-
|
405
|
+
|
406
|
+
#
|
407
|
+
# Read a file.
|
408
|
+
# The file can be streamed in chunks and also fetched as partial content
|
409
|
+
# based on the range header specified in the request.
|
410
|
+
# Only authorised requests can invoke the API.
|
411
|
+
#
|
412
|
+
# Usage: my_client.nfs.get_file("/docs/hello.txt")
|
413
|
+
# Adv.Usage: my_client.nfs.get_file("/docs/hello.txt", range: "bytes 0-1000", root_path: "app")
|
414
|
+
# Fail: {"errorCode"=>-1503, "description"=>"FfiError::InvalidPath"}
|
415
|
+
# Success: {"headers"=>{"x-powered-by"=>"Express", "content-range"=>"bytes 0-4/4", "accept-ranges"=>"bytes", "content-length"=>"4", "created-on"=>"2016-08-14T12:51:18.924Z", "last-modified"=>"2016-08-14T12:51:18.935Z", "content-type"=>"text/plain", "date"=>"Sun, 14 Aug 2016 13:30:07 GMT", "connection"=>"close"}, "body"=>"Test"}
|
416
|
+
#
|
417
|
+
# Reference: https://maidsafe.readme.io/docs/nfs-get-file
|
418
|
+
#
|
386
419
|
def get_file(file_path, options = {})
|
387
|
-
#
|
388
|
-
options[:offset]
|
389
|
-
options[:
|
420
|
+
# Default values
|
421
|
+
options[:offset] = 0 if ! options.has_key?(:offset)
|
422
|
+
options[:root_path] = 'app' if ! options.has_key?(:root_path)
|
390
423
|
|
391
|
-
#
|
392
|
-
url = "#{@client.app_info[:launcher_server]}nfs/file/#{CGI.escape(file_path)}
|
424
|
+
# Entry point
|
425
|
+
url = "#{@client.app_info[:launcher_server]}nfs/file/#{options[:root_path]}/#{CGI.escape(file_path)}?"
|
393
426
|
|
394
|
-
#
|
427
|
+
# Query params
|
395
428
|
query = []
|
396
429
|
query << "offset=#{options[:offset]}"
|
397
430
|
query << "length=#{options[:length]}" if options.has_key?(:length) # length is optional
|
398
|
-
url = "#{url}#{
|
431
|
+
url = "#{url}#{query.join('&')}"
|
399
432
|
|
400
|
-
#
|
433
|
+
# API call
|
401
434
|
uri = URI(url)
|
402
435
|
http = Net::HTTP.new(uri.host, uri.port)
|
403
|
-
|
436
|
+
headers = {
|
404
437
|
'Authorization' => "Bearer #{@client.key_helper.get_valid_token()}",
|
405
|
-
}
|
438
|
+
}
|
439
|
+
headers["Range"] = options[:range] if options.has_key?(:range)
|
440
|
+
req = Net::HTTP::Get.new(uri.path, headers)
|
406
441
|
res = http.request(req)
|
407
|
-
|
442
|
+
res_headers = {}
|
443
|
+
res.response.each_header {|k,v| res_headers[k] = v}
|
444
|
+
res.code == "200" ? {"headers" => res_headers, "body" => res.body} : JSON.parse(res.body)
|
408
445
|
end
|
409
446
|
|
410
|
-
def update_file_content(file_path, contents, options = {})
|
411
|
-
# default values
|
412
|
-
options[:offset] = 0 if ! options.has_key?(:offset)
|
413
|
-
options[:is_path_shared] = false if ! options.has_key?(:is_path_shared)
|
414
447
|
|
415
|
-
|
416
|
-
|
448
|
+
#
|
449
|
+
# Rename a file and (optionally) update its metadata.
|
450
|
+
# Only authorised requests can invoke the API.
|
451
|
+
#
|
452
|
+
# Usage: my_client.nfs.update_file_metadata("/docs/hello.txt")
|
453
|
+
# Adv.Usage: my_client.nfs.get_file("/docs/hello.txt", range: "bytes 0-1000", root_path: "app")
|
454
|
+
# Fail: {"errorCode"=>-1503, "description"=>"FfiError::InvalidPath"}
|
455
|
+
# Success: {"headers"=>{"x-powered-by"=>"Express", "content-range"=>"bytes 0-4/4", "accept-ranges"=>"bytes", "content-length"=>"4", "created-on"=>"2016-08-14T12:51:18.924Z", "last-modified"=>"2016-08-14T12:51:18.935Z", "content-type"=>"text/plain", "date"=>"Sun, 14 Aug 2016 13:30:07 GMT", "connection"=>"close"}, "body"=>"Test"}
|
456
|
+
#
|
457
|
+
# Reference: https://maidsafe.readme.io/docs/nfs-update-file-metadata
|
458
|
+
#
|
459
|
+
def update_file_meta(file_path, options = {})
|
460
|
+
# Default values
|
461
|
+
options[:root_path] = 'app' if ! options.has_key?(:root_path)
|
417
462
|
|
418
|
-
#
|
463
|
+
# Entry point
|
464
|
+
url = "#{@client.app_info[:launcher_server]}nfs/file/metadata/#{options[:root_path]}/#{CGI.escape(file_path)}"
|
465
|
+
|
466
|
+
# Optional payload
|
467
|
+
payload = {}
|
468
|
+
payload["name"] = CGI.escape(options[:name]) if options.has_key?(:name)
|
469
|
+
payload["metadata"] = Base64.strict_encode64(options[:meta]) if options.has_key?(:meta)
|
470
|
+
|
471
|
+
# API call
|
419
472
|
uri = URI(url)
|
420
473
|
http = Net::HTTP.new(uri.host, uri.port)
|
421
474
|
req = Net::HTTP::Put.new(uri.path, {
|
422
475
|
'Authorization' => "Bearer #{@client.key_helper.get_valid_token()}",
|
423
|
-
'Content-Type' => '
|
476
|
+
'Content-Type' => 'application/json'
|
424
477
|
})
|
425
|
-
req.body =
|
478
|
+
req.body = payload.to_json
|
426
479
|
res = http.request(req)
|
427
|
-
res.code == "200" ? true : JSON.parse(
|
480
|
+
res.code == "200" ? true : JSON.parse(res.body)
|
481
|
+
end
|
482
|
+
|
483
|
+
# Alias
|
484
|
+
def rename_file(file_path, new_name, options = {})
|
485
|
+
options[:name] = new_name
|
486
|
+
self.update_file_meta(file_path)
|
428
487
|
end
|
429
488
|
|
489
|
+
|
490
|
+
#
|
491
|
+
# Delete a file.
|
492
|
+
# Only authorised requests can invoke the API.
|
493
|
+
#
|
494
|
+
# Usage: my_client.nfs.delete_file("/docs/hello.txt")
|
495
|
+
# Adv.Usage: my_client.nfs.delete_file("/docs/hello.txt", root_path: "app")
|
496
|
+
# Fail: {"errorCode"=>-1503, "description"=>"FfiError::InvalidPath"}
|
497
|
+
# Success: true
|
498
|
+
#
|
499
|
+
# Reference: https://maidsafe.readme.io/docs/nfs-delete-file
|
500
|
+
#
|
430
501
|
def delete_file(file_path, options = {})
|
431
|
-
#
|
432
|
-
options[:
|
502
|
+
# Default values
|
503
|
+
options[:root_path] = 'app' if ! options.has_key?(:root_path)
|
433
504
|
|
434
|
-
#
|
435
|
-
url = "#{@client.app_info[:launcher_server]}nfs/file/#{CGI.escape(file_path)}
|
505
|
+
# Entry point
|
506
|
+
url = "#{@client.app_info[:launcher_server]}nfs/file/#{options[:root_path]}/#{CGI.escape(file_path)}"
|
436
507
|
|
437
|
-
#
|
508
|
+
# API call
|
438
509
|
uri = URI(url)
|
439
510
|
http = Net::HTTP.new(uri.host, uri.port)
|
440
511
|
req = Net::HTTP::Delete.new(uri.path, {
|
441
512
|
'Authorization' => "Bearer #{@client.key_helper.get_valid_token()}",
|
442
513
|
})
|
443
514
|
res = http.request(req)
|
444
|
-
res.code == "200" ? true : JSON.parse(
|
515
|
+
res.code == "200" ? true : JSON.parse(res.body)
|
445
516
|
end
|
446
517
|
end
|
447
518
|
|
@@ -451,7 +522,16 @@ module SafeNet
|
|
451
522
|
@client = client_obj
|
452
523
|
end
|
453
524
|
|
454
|
-
#
|
525
|
+
#
|
526
|
+
# Register a long name. Long names are public names that can be shared.
|
527
|
+
# Only authorised requests can invoke the API.
|
528
|
+
#
|
529
|
+
# Usage: my_client.dns.create_long_name("my-domain")
|
530
|
+
# Fail: {"errorCode"=>-1503, "description"=>"FfiError::InvalidPath"}
|
531
|
+
# Success: true
|
532
|
+
#
|
533
|
+
# Reference: https://maidsafe.readme.io/docs/dns-create-long-name
|
534
|
+
#
|
455
535
|
def create_long_name(long_name)
|
456
536
|
# entry point
|
457
537
|
url = "#{@client.app_info[:launcher_server]}dns/#{CGI.escape(long_name)}"
|
@@ -464,42 +544,83 @@ module SafeNet
|
|
464
544
|
'Content-Type' => 'text/plain'
|
465
545
|
})
|
466
546
|
res = http.request(req)
|
467
|
-
res.code == "200" ? true : JSON.parse(
|
547
|
+
res.code == "200" ? true : JSON.parse(res.body)
|
468
548
|
end
|
469
549
|
|
470
550
|
|
471
|
-
#
|
472
|
-
#
|
551
|
+
#
|
552
|
+
# Register a long name and a service.
|
553
|
+
# Only authorised requests can invoke the API.
|
554
|
+
#
|
555
|
+
# Usage: my_client.dns.register_service("my-domain", "www", "/sources")
|
556
|
+
# Fail: {"errorCode"=>-1503, "description"=>"FfiError::InvalidPath"}
|
557
|
+
# Success: true
|
558
|
+
#
|
559
|
+
# Reference: https://maidsafe.readme.io/docs/dns-register-service
|
560
|
+
#
|
473
561
|
def register_service(long_name, service_name, service_home_dir_path, options = {})
|
474
|
-
#
|
562
|
+
# Entry point
|
475
563
|
url = "#{@client.app_info[:launcher_server]}dns"
|
476
564
|
|
477
|
-
#
|
478
|
-
options[:is_path_shared] = false if ! options.has_key?(:is_path_shared)
|
479
|
-
|
480
|
-
# payload
|
565
|
+
# Payload
|
481
566
|
payload = {
|
482
567
|
longName: long_name,
|
483
568
|
serviceName: service_name,
|
569
|
+
rootPath: 'app',
|
484
570
|
serviceHomeDirPath: service_home_dir_path,
|
485
|
-
isPathShared: options[:is_path_shared]
|
486
571
|
}
|
487
572
|
|
488
|
-
#
|
489
|
-
payload["metadata"] = options[:
|
573
|
+
# Optional
|
574
|
+
payload["metadata"] = options[:meta] if options.has_key?(:meta)
|
490
575
|
|
491
|
-
#
|
576
|
+
# API call
|
492
577
|
uri = URI(url)
|
493
578
|
http = Net::HTTP.new(uri.host, uri.port)
|
494
579
|
req = Net::HTTP::Post.new(uri.path, {
|
495
580
|
'Authorization' => "Bearer #{@client.key_helper.get_valid_token()}",
|
496
|
-
'Content-Type' => '
|
581
|
+
'Content-Type' => 'application/json'
|
497
582
|
})
|
498
|
-
req.body =
|
583
|
+
req.body = payload.to_json
|
499
584
|
res = http.request(req)
|
500
|
-
res.code == "200" ? true : JSON.parse(
|
585
|
+
res.code == "200" ? true : JSON.parse(res.body)
|
501
586
|
end
|
502
587
|
|
588
|
+
|
589
|
+
#
|
590
|
+
# Add a service to a registered long name.
|
591
|
+
# Only authorised requests can invoke the API.
|
592
|
+
#
|
593
|
+
# Usage: my_client.dns.add_service("my-domain", "www", "/sources")
|
594
|
+
# Fail: {"errorCode"=>-1503, "description"=>"FfiError::InvalidPath"}
|
595
|
+
# Success: true
|
596
|
+
#
|
597
|
+
# Reference: https://maidsafe.readme.io/docs/dns
|
598
|
+
#
|
599
|
+
def add_service(long_name, service_name, service_home_dir_path)
|
600
|
+
# Entry point
|
601
|
+
url = "#{@client.app_info[:launcher_server]}dns"
|
602
|
+
|
603
|
+
# Payload
|
604
|
+
payload = {
|
605
|
+
longName: long_name,
|
606
|
+
serviceName: service_name,
|
607
|
+
rootPath: 'app',
|
608
|
+
serviceHomeDirPath: service_home_dir_path,
|
609
|
+
}
|
610
|
+
|
611
|
+
# API call
|
612
|
+
uri = URI(url)
|
613
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
614
|
+
req = Net::HTTP::Put.new(uri.path, {
|
615
|
+
'Authorization' => "Bearer #{@client.key_helper.get_valid_token()}",
|
616
|
+
'Content-Type' => 'application/json'
|
617
|
+
})
|
618
|
+
req.body = payload.to_json
|
619
|
+
res = http.request(req)
|
620
|
+
res.code == "200" ? true : JSON.parse(res.body)
|
621
|
+
end
|
622
|
+
|
623
|
+
|
503
624
|
# https://maidsafe.readme.io/docs/dns-list-long-names
|
504
625
|
def list_long_names
|
505
626
|
# entry point
|
@@ -512,7 +633,7 @@ module SafeNet
|
|
512
633
|
'Authorization' => "Bearer #{@client.key_helper.get_valid_token()}",
|
513
634
|
})
|
514
635
|
res = http.request(req)
|
515
|
-
JSON.parse(
|
636
|
+
JSON.parse(res.body)
|
516
637
|
end
|
517
638
|
|
518
639
|
# https://maidsafe.readme.io/docs/dns-list-services
|
@@ -527,7 +648,7 @@ module SafeNet
|
|
527
648
|
'Authorization' => "Bearer #{@client.key_helper.get_valid_token()}",
|
528
649
|
})
|
529
650
|
res = http.request(req)
|
530
|
-
JSON.parse(
|
651
|
+
JSON.parse(res.body)
|
531
652
|
end
|
532
653
|
|
533
654
|
|
@@ -541,31 +662,26 @@ module SafeNet
|
|
541
662
|
http = Net::HTTP.new(uri.host, uri.port)
|
542
663
|
req = Net::HTTP::Get.new(uri.path)
|
543
664
|
res = http.request(req)
|
544
|
-
JSON.parse(res.body)
|
665
|
+
res = JSON.parse(res.body)
|
666
|
+
res["info"]["metadata"] = Base64.strict_decode64(res["info"]["metadata"]) if res.has_key?("info") && res["info"].has_key?("metadata")
|
667
|
+
res
|
545
668
|
end
|
546
669
|
|
547
670
|
|
548
671
|
# https://maidsafe.readme.io/docs/dns-get-file-unauth
|
549
|
-
# get_file_unauth("thegoogle", "www", "index.html"
|
550
|
-
def get_file_unauth(long_name, service_name, file_path
|
551
|
-
# default values
|
552
|
-
options[:offset] = 0 if ! options.has_key?(:offset)
|
553
|
-
|
672
|
+
# get_file_unauth("thegoogle", "www", "index.html")
|
673
|
+
def get_file_unauth(long_name, service_name, file_path)
|
554
674
|
# entry point
|
555
|
-
url = "#{@client.app_info[:launcher_server]}dns/#{CGI.escape(service_name)}/#{CGI.escape(long_name)}/#{CGI.escape(file_path)}
|
556
|
-
|
557
|
-
# query params are encrypted
|
558
|
-
query = []
|
559
|
-
query << "offset=#{options[:offset]}"
|
560
|
-
query << "length=#{options[:length]}" if options.has_key?(:length) # length is optional
|
561
|
-
url = "#{url}#{@client.key_helper.encrypt(query.join('&'))}"
|
675
|
+
url = "#{@client.app_info[:launcher_server]}dns/#{CGI.escape(service_name)}/#{CGI.escape(long_name)}/#{CGI.escape(file_path)}"
|
562
676
|
|
563
677
|
# api call
|
564
678
|
uri = URI(url)
|
565
679
|
http = Net::HTTP.new(uri.host, uri.port)
|
566
680
|
req = Net::HTTP::Get.new(uri.path)
|
567
681
|
res = http.request(req)
|
568
|
-
|
682
|
+
res_headers = {}
|
683
|
+
res.response.each_header {|k,v| res_headers[k] = v}
|
684
|
+
res.code == "200" ? {"headers" => res_headers, "body" => res.body} : JSON.parse(res.body)
|
569
685
|
end
|
570
686
|
end
|
571
687
|
|
@@ -575,26 +691,37 @@ module SafeNet
|
|
575
691
|
end
|
576
692
|
|
577
693
|
def create(id, tag_type, contents)
|
578
|
-
|
694
|
+
return { "errorCode" => -99991, "description" => "SD max size currently limited to 70k" } if contents.size > 1024 * 70
|
579
695
|
new_id = Digest::SHA2.new(512).hexdigest("#{id}#{tag_type}")
|
580
|
-
res = @client.nfs.
|
581
|
-
res
|
582
|
-
|
583
|
-
|
696
|
+
res = @client.nfs.create_public_directory("/_sds/#{new_id}", meta: contents)
|
697
|
+
if res != true
|
698
|
+
if res["errorCode"] == -1502 # "_sds" directory doesn't exist
|
699
|
+
@client.nfs.create_public_directory("/_sds")
|
700
|
+
res = @client.nfs.create_public_directory("/_sds/#{new_id}", meta: contents) == true
|
701
|
+
else # unknown error
|
702
|
+
res = false
|
703
|
+
end
|
704
|
+
end
|
705
|
+
res &&= @client.dns.register_service("sd#{new_id[0..48]}", "sds", "/_sds/#{new_id}") == true
|
584
706
|
res
|
585
707
|
end
|
586
708
|
|
587
709
|
def update(id, tag_type, contents)
|
588
|
-
version = 1
|
589
710
|
new_id = Digest::SHA2.new(512).hexdigest("#{id}#{tag_type}")
|
590
|
-
res = @client.nfs.
|
711
|
+
res = @client.nfs.update_directory("/_sds/#{new_id}", meta: contents)
|
712
|
+
if res != true
|
713
|
+
if res["errorCode"] == -1502 # SD doesn't exist yet
|
714
|
+
res = self.create(id, tag_type, contents) == true
|
715
|
+
else # unknown error
|
716
|
+
res = false
|
717
|
+
end
|
718
|
+
end
|
591
719
|
res
|
592
720
|
end
|
593
721
|
|
594
722
|
def get(id, tag_type)
|
595
|
-
version = 1
|
596
723
|
new_id = Digest::SHA2.new(512).hexdigest("#{id}#{tag_type}")
|
597
|
-
@client.dns.
|
724
|
+
@client.dns.get_home_dir("sd#{new_id[0..48]}", "sds").try(:[], "info").try(:[], "metadata")
|
598
725
|
end
|
599
726
|
end
|
600
727
|
|
data/ruby-safenet.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-safenet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Loureiro
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rbnacl
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '3.3'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '3.3'
|
55
41
|
description: Ruby library for accessing the SAFE network
|
56
42
|
email:
|
57
43
|
- loureirorg@gmail.com
|
@@ -88,9 +74,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
74
|
version: '0'
|
89
75
|
requirements: []
|
90
76
|
rubyforge_project:
|
91
|
-
rubygems_version: 2.
|
77
|
+
rubygems_version: 2.5.1
|
92
78
|
signing_key:
|
93
79
|
specification_version: 4
|
94
80
|
summary: Ruby library for accessing the SAFE network
|
95
81
|
test_files: []
|
96
|
-
has_rdoc:
|