ruby-safenet 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
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: