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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 715ff6f246885377bf8dc67d3e51476966c2a39c
4
- data.tar.gz: 426547e4d0a810938f6330b93a8c81c9d7dce252
3
+ metadata.gz: ca8bf637841001a2a3edffcdaf9f7604f50e5714
4
+ data.tar.gz: 9595c12476853bd050a3a0caa576b018a2892bfc
5
5
  SHA512:
6
- metadata.gz: 2012bfc016585980a254f1387c7f758fede3de626007846473a49c573768861c102369d19fe727a3777924fdde17cf61852a4a7ec70d02e80044985489b0e969
7
- data.tar.gz: 1134b7912d810184d156990c8942be6bfa7dfdcedfddf9d8a0f2da099c6dd88803be00e7df535c37729d1f4bf4518019a738c2b11fa1c9516b0ba351978de5ea
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.create_directory("/mydir", is_private: false)
17
- my_client.nfs.file("/mydir/index.html", is_private: false)
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.dns.get_file("/mydir/index.html")
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: "org.thevendor.demo",
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.file("/mydir/dog.jpg")
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.create(37267, 11, "Hello World") # 37267 = id, 11 = tag_type
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/proposed/0028-launcher-low-level-api/0028-launcher-low-level-api.md
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|create|id, tag_type, contents|||
78
- |sd|update|id, tag_type, contents|||
79
- |sd|get|id, tag_type|||
80
- |nfs|create_directory|dir_path|is_private, is_versioned, is_path_shared|https://maidsafe.readme.io/docs/nfs-create-directory|
81
- |nfs|get_directory|dir_path|is_path_shared|https://maidsafe.readme.io/docs/nfs-get-directory|
82
- |nfs|delete_directory|dir_path|is_path_shared|https://maidsafe.readme.io/docs/nfs-create-directory|
83
- |nfs|file|file_path|is_private, is_versioned, is_path_shared|https://maidsafe.readme.io/docs/nfsfile|
84
- |nfs|get_file|file_path|is_path_shared, offset, length|https://maidsafe.readme.io/docs/nfs-get-file|
85
- |nfs|update_file_content|file_path, contents|is_path_shared, offset|https://maidsafe.readme.io/docs/nfs-update-file-content|
86
- |nfs|delete_file|file_path|is_path_shared|https://maidsafe.readme.io/docs/nfs-delete-file|
87
- |dns|create_long_name|long_name||https://maidsafe.readme.io/docs/dns-create-long-name|
88
- |dns|register_service|long_name, service_name, service_home_dir_path|is_path_shared, metadata|https://maidsafe.readme.io/docs/dns-register-service|
89
- |dns|list_long_names||is_path_shared, metadata|https://maidsafe.readme.io/docs/dns-list-long-names|
90
- |dns|list_services|long_name||https://maidsafe.readme.io/docs/dns-list-services|
91
- |dns|get_home_dir|long_name, service_name||https://maidsafe.readme.io/docs/dns-get-home-dir|
92
- |dns|get_file_unauth|long_name, service_name, file_path|offset, length|https://maidsafe.readme.io/docs/dns-get-file-unauth|
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
@@ -1,3 +1,3 @@
1
1
  module Safenet
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.4"
3
3
  end
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
- # An application exchanges data with the SAFE Launcher using symmetric key
126
- # encryption. The symmetric key is session based and is securely transferred
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
- # The application will initiate the authorisation request with the generated
132
- # nonce and public key, along with information about the application and the
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 SAFE Launcher will prompt to the user with the application information
136
- # along with the requested permissions. Once the user authorises the
137
- # request, the symmetric keys for encryption are received. If the user
138
- # denies the request then the SAFE Launcher sends an unauthorised error
139
- # response.
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", encryptedKey: "232", "publicKey": "4323", "permissions": []}
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
- publicKey: Base64.strict_encode64(private_key.public_key),
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
- # To check whether the authorisation token obtained is valid.
199
- # The Authorization header must be present in the request.
134
+ # Check whether the authorisation token obtained from SAFE Launcher is still
135
+ # valid.
200
136
  #
201
- # Usage: SafeNet.is_token_valid()
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
- # Removes the token from the SAFE Launcher.
159
+ # Revoke the authorisation token obtained from SAFE Launcher.
224
160
  #
225
- # Usage: SafeNet.revoke_token()
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 using the NFS API.
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: SafeNet.get_directory("/photos", is_path_shared: false)
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"=> "Ruby Demo App-Root-Dir", ...}, ...}
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
- # default values
264
- options[:is_path_shared] = false if ! options.has_key?(:is_path_shared)
251
+ # Default values
252
+ options[:root_path] = 'app' if ! options.has_key?(:root_path)
265
253
 
266
- # entry point
267
- url = "#{@client.app_info[:launcher_server]}nfs/directory/#{CGI.escape(dir_path)}/#{options[:is_path_shared]}"
254
+ # Entry point
255
+ url = "#{@client.app_info[:launcher_server]}nfs/directory/#{options[:root_path]}/#{CGI.escape(dir_path)}"
268
256
 
269
- # api call
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(@client.key_helper.decrypt(res.body))
264
+ JSON.parse(res.body)
277
265
  end
278
266
 
279
267
 
280
268
  #
281
- # Create a File using the NFS API.
282
- # Only authorised requests can invoke the API.
269
+ # Rename a directory and (optionally) update its metadata.
270
+ # Only authorised requests can invoke this API.
283
271
  #
284
- # Usage: SafeNet.file("/photos/cat.jpg")
285
- # Adv.Usage: SafeNet.file("/photos/cat.jpg", is_private: true, metadata: "some meta", is_path_shared: false, is_versioned: false)
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/nfsfile
277
+ # Reference: https://maidsafe.readme.io/docs/nfs-update-directory
290
278
  #
291
- def file(file_path, options = {})
292
- url = "#{@client.app_info[:launcher_server]}nfs/file"
279
+ def update_directory(dir_path, options = {})
280
+ # Default values
281
+ options[:root_path] = 'app' if ! options.has_key?(:root_path)
293
282
 
294
- # default values
295
- options[:is_private] = true if ! options.has_key?(:is_private)
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
- filePath: file_path,
302
- isPrivate: options[:is_private],
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
- # api call
291
+ # API call
311
292
  uri = URI(url)
312
293
  http = Net::HTTP.new(uri.host, uri.port)
313
- req = Net::HTTP::Post.new(uri.path, {
294
+ req = Net::HTTP::Put.new(uri.path, {
314
295
  'Authorization' => "Bearer #{@client.key_helper.get_valid_token()}",
315
- 'Content-Type' => 'text/plain'
296
+ 'Content-Type' => 'application/json'
316
297
  })
317
- req.body = @client.key_helper.encrypt(payload.to_json)
298
+ req.body = payload.to_json
318
299
  res = http.request(req)
319
- res.code == "200" ? true : JSON.parse(@client.key_helper.decrypt(res.body))
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
- # Create a directory using the NFS API.
325
- # Only authorised requests can create a directory.
310
+ # Delete a directory.
311
+ # Only authorised requests can invoke this API.
326
312
  #
327
- # Usage: SafeNet.create_directory("/photos")
328
- # Adv.Usage: SafeNet.create_directory("/photos", is_private: true, metadata: "some meta", is_path_shared: false, is_versioned: false)
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-create-directory
318
+ # Reference: https://maidsafe.readme.io/docs/nfs-delete-directory
333
319
  #
334
- def create_directory(dir_path, options = {})
335
- # entry point
336
- url = "#{@client.app_info[:launcher_server]}nfs/directory"
320
+ def delete_directory(dir_path, options = {})
321
+ # Default values
322
+ options[:root_path] = 'app' if ! options.has_key?(:root_path)
337
323
 
338
- # default values
339
- options[:is_private] = true if ! options.has_key?(:is_private)
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
- # payload
344
- payload = {
345
- dirPath: dir_path,
346
- isPrivate: options[:is_private],
347
- isVersioned: options[:is_versioned],
348
- isPathShared: options[:is_path_shared]
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
- # api call
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
- req = Net::HTTP::Post.new(uri.path, {
360
+ headers = {
358
361
  'Authorization' => "Bearer #{@client.key_helper.get_valid_token()}",
359
- 'Content-Type' => 'text/plain'
360
- })
361
- req.body = @client.key_helper.encrypt(payload.to_json)
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(@client.key_helper.decrypt(res.body))
369
+ res.code == "200" ? true : JSON.parse(res.body)
364
370
  end
365
371
 
366
372
 
367
- # ex.: delete_directory("/photos")
368
- def delete_directory(dir_path, options = {})
369
- # default values
370
- options[:is_path_shared] = false if ! options.has_key?(:is_path_shared)
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
- # entry point
373
- url = "#{@client.app_info[:launcher_server]}nfs/directory/#{CGI.escape(dir_path)}/#{options[:is_path_shared]}"
388
+ # Entry point
389
+ url = "#{@client.app_info[:launcher_server]}nfs/file/#{options[:root_path]}/#{CGI.escape(file_path)}"
374
390
 
375
- # api call
391
+ # API call
376
392
  uri = URI(url)
377
393
  http = Net::HTTP.new(uri.host, uri.port)
378
- req = Net::HTTP::Delete.new(uri.path, {
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
- res.code == "200" ? true : JSON.parse(@client.key_helper.decrypt(res.body))
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
- # options: offset, length, is_path_shared
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
- # default values
388
- options[:offset] = 0 if ! options.has_key?(:offset)
389
- options[:is_path_shared] = false if ! options.has_key?(:is_path_shared)
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
- # entry point
392
- url = "#{@client.app_info[:launcher_server]}nfs/file/#{CGI.escape(file_path)}/#{options[:is_path_shared]}?"
424
+ # Entry point
425
+ url = "#{@client.app_info[:launcher_server]}nfs/file/#{options[:root_path]}/#{CGI.escape(file_path)}?"
393
426
 
394
- # query params are encrypted
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}#{@client.key_helper.encrypt(query.join('&'))}"
431
+ url = "#{url}#{query.join('&')}"
399
432
 
400
- # api call
433
+ # API call
401
434
  uri = URI(url)
402
435
  http = Net::HTTP.new(uri.host, uri.port)
403
- req = Net::HTTP::Get.new(uri.path, {
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
- res.code == "200" ? @client.key_helper.decrypt(res.body) : JSON.parse(@client.key_helper.decrypt(res.body))
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
- # entry point
416
- url = "#{@client.app_info[:launcher_server]}nfs/file/#{CGI.escape(file_path)}/#{options[:is_path_shared]}?offset=#{options[:offset]}"
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
- # api call
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' => 'text/plain'
476
+ 'Content-Type' => 'application/json'
424
477
  })
425
- req.body = @client.key_helper.encrypt(contents)
478
+ req.body = payload.to_json
426
479
  res = http.request(req)
427
- res.code == "200" ? true : JSON.parse(@client.key_helper.decrypt(res.body))
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
- # default values
432
- options[:is_path_shared] = false if ! options.has_key?(:is_path_shared)
502
+ # Default values
503
+ options[:root_path] = 'app' if ! options.has_key?(:root_path)
433
504
 
434
- # entry point
435
- url = "#{@client.app_info[:launcher_server]}nfs/file/#{CGI.escape(file_path)}/#{options[:is_path_shared]}"
505
+ # Entry point
506
+ url = "#{@client.app_info[:launcher_server]}nfs/file/#{options[:root_path]}/#{CGI.escape(file_path)}"
436
507
 
437
- # api call
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(@client.key_helper.decrypt(res.body))
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
- # https://maidsafe.readme.io/docs/dns-create-long-name
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(@client.key_helper.decrypt(res.body))
547
+ res.code == "200" ? true : JSON.parse(res.body)
468
548
  end
469
549
 
470
550
 
471
- # ex.: register_service("thegoogle", "www", "/www")
472
- # https://maidsafe.readme.io/docs/dns-register-service
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
- # entry point
562
+ # Entry point
475
563
  url = "#{@client.app_info[:launcher_server]}dns"
476
564
 
477
- # default values
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
- # optional
489
- payload["metadata"] = options[:metadata] if options.has_key?(:metadata)
573
+ # Optional
574
+ payload["metadata"] = options[:meta] if options.has_key?(:meta)
490
575
 
491
- # api call
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' => 'text/plain'
581
+ 'Content-Type' => 'application/json'
497
582
  })
498
- req.body = @client.key_helper.encrypt(payload.to_json)
583
+ req.body = payload.to_json
499
584
  res = http.request(req)
500
- res.code == "200" ? true : JSON.parse(@client.key_helper.decrypt(res.body))
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(@client.key_helper.decrypt(res.body))
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(@client.key_helper.decrypt(res.body))
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", offset: 3, length: 5)
550
- def get_file_unauth(long_name, service_name, file_path, options = {})
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
- res.code == "200" ? res.body : JSON.parse(res.body)
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
- version = 1
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.create_directory("/#{new_id}", is_private: false) == true
581
- res &&= @client.nfs.file("/#{new_id}/data.#{version}", is_private: false) == true
582
- res &&= @client.nfs.update_file_content("/#{new_id}/data.#{version}", contents) == true
583
- res &&= @client.dns.register_service("SD#{new_id}", "sd", "/#{new_id}") == true
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.update_file_content("/#{new_id}/data.#{version}", contents) == true
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.get_file_unauth("SD#{new_id}", "sd", "data.#{version}")
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
@@ -28,5 +28,4 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  spec.add_development_dependency "bundler", "~> 1.10"
30
30
  spec.add_development_dependency "rake", "~> 10.0"
31
- spec.add_runtime_dependency "rbnacl", "~> 3.3"
32
31
  end
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.3
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-04-17 00:00:00.000000000 Z
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.4.8
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: