megar 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.gitignore +19 -0
  2. data/.rspec +1 -0
  3. data/.rvmrc +1 -0
  4. data/.travis.yml +11 -0
  5. data/CHANGELOG +5 -0
  6. data/Gemfile +4 -0
  7. data/Guardfile +11 -0
  8. data/LICENSE +22 -0
  9. data/README.rdoc +218 -0
  10. data/Rakefile +33 -0
  11. data/bin/megar +16 -0
  12. data/lib/extensions/math.rb +13 -0
  13. data/lib/js_ref_impl/_README +9 -0
  14. data/lib/js_ref_impl/base64_1.js +83 -0
  15. data/lib/js_ref_impl/crypto_5.js +1795 -0
  16. data/lib/js_ref_impl/download_8.js +867 -0
  17. data/lib/js_ref_impl/hex_1.js +76 -0
  18. data/lib/js_ref_impl/index_9.js +666 -0
  19. data/lib/js_ref_impl/js.manifest +115 -0
  20. data/lib/js_ref_impl/rsa_1.js +456 -0
  21. data/lib/js_ref_impl/sjcl_1.js +1 -0
  22. data/lib/js_ref_impl/upload_10.js +691 -0
  23. data/lib/megar.rb +11 -0
  24. data/lib/megar/catalog.rb +5 -0
  25. data/lib/megar/catalog/catalog_item.rb +90 -0
  26. data/lib/megar/catalog/file.rb +14 -0
  27. data/lib/megar/catalog/files.rb +13 -0
  28. data/lib/megar/catalog/folder.rb +20 -0
  29. data/lib/megar/catalog/folders.rb +28 -0
  30. data/lib/megar/connection.rb +84 -0
  31. data/lib/megar/crypto.rb +399 -0
  32. data/lib/megar/exception.rb +55 -0
  33. data/lib/megar/session.rb +157 -0
  34. data/lib/megar/shell.rb +87 -0
  35. data/lib/megar/version.rb +3 -0
  36. data/megar.gemspec +30 -0
  37. data/spec/fixtures/crypto_expectations/sample_user.json +109 -0
  38. data/spec/spec_helper.rb +24 -0
  39. data/spec/support/crypto_expectations_helper.rb +44 -0
  40. data/spec/support/mocks_helper.rb +22 -0
  41. data/spec/unit/catalog/file_spec.rb +31 -0
  42. data/spec/unit/catalog/files_spec.rb +26 -0
  43. data/spec/unit/catalog/folder_spec.rb +28 -0
  44. data/spec/unit/catalog/folders_spec.rb +49 -0
  45. data/spec/unit/connection_spec.rb +50 -0
  46. data/spec/unit/crypto_spec.rb +476 -0
  47. data/spec/unit/exception_spec.rb +35 -0
  48. data/spec/unit/extensions/math_spec.rb +21 -0
  49. data/spec/unit/session_spec.rb +146 -0
  50. data/spec/unit/shell_spec.rb +18 -0
  51. metadata +238 -0
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ *.trace
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ spec/sandpit
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3@megar --create
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ # These are specific configuration settings required for travis-ci
2
+ # see http://travis-ci.org/evendis/megar
3
+ language: ruby
4
+ rvm:
5
+ # - 1.8.7
6
+ # - 1.9.2
7
+ - 1.9.3
8
+ # - rbx-18mode
9
+ # - rbx-19mode
10
+ # - jruby-18mode
11
+ # - jruby-19mode
data/CHANGELOG ADDED
@@ -0,0 +1,5 @@
1
+ 0.0.1 Preliminary Release 26-Feb-2013
2
+ ======================================
3
+ * An initial release with minimal functionality
4
+ * API support: connect and get file/folder listings
5
+ * basic CLI to connect and get file listing
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in megar.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,11 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2, :all_on_start => false, :all_after_pass => false do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/megar/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" }
7
+ watch(%r{^lib/extensions/(.+)\.rb$}) { |m| "spec/unit/extensions/#{m[1]}_spec.rb" }
8
+ watch('spec/spec_helper.rb') { "spec" }
9
+
10
+ end
11
+
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Paul Gallagher
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,218 @@
1
+ = Megar {<img src="https://secure.travis-ci.org/tardate/megar.png" />}[http://travis-ci.org/tardate/megar]
2
+
3
+ Megar ("megaargh!" in pirate-speak) is a Ruby wrapper and command-line (CLI) client for the {Mega API}[https://mega.co.nz/#developers].
4
+
5
+ It needs a few more API functions implemented to make it halfway useful, but it's a start.
6
+ You can connect and get file/folder listings at the moment.
7
+
8
+ == Requirements and Known Limitations
9
+
10
+ Consider this totally alpha at this point, especially since the Mega API has yet to be formally and fully documented.
11
+
12
+ * Currently tested with MRI 1.9.3
13
+ * MRI 1.9.2 and 2.x not yet tested
14
+ * Rubinius and JRuby 1.9 modes not yet tested
15
+ * No plans to support 1.8 Ruby branches
16
+
17
+ Mega API coverage is far from complete at this point (help appreciated!). Here's the run-down:
18
+
19
+ Supported API functions:
20
+ * User/session management: Complete accounts
21
+ * Login session challenge/response
22
+ * Retrieve file and folder nodes
23
+
24
+ Currently unsupported API functions:
25
+ * User/session management: Ephemeral accounts
26
+ * User/session management: Confirming accounts
27
+ * Retrieve user nodes
28
+ * Add/copy nodes
29
+ * Delete node
30
+ * Move node
31
+ * Set node attributes
32
+ * Create/delete public handle
33
+ * Create/modify/delete outgoing share
34
+ * Key handling - Set or request share/node keys
35
+ * Request download URL
36
+ * Request upload URL
37
+ * Add/update user
38
+ * Get user
39
+ * Retrieve user's public key
40
+ * Add/update/delete contact
41
+ * Invite user
42
+ * Send confirmation e-mail
43
+ * Obtain user details by invitation code
44
+ * Verify e-mailed confirmation code
45
+ * List user sessions
46
+ * User quota details
47
+ * ... and any other API features not explicitly listed above
48
+
49
+
50
+ == The Megar Cookbook
51
+
52
+ === How do I install it for normal use?
53
+
54
+ Add this line to your application's Gemfile:
55
+
56
+ gem 'megar'
57
+
58
+ And then execute:
59
+
60
+ $ bundle
61
+
62
+ Or install it yourself as:
63
+
64
+ $ gem install megar
65
+
66
+
67
+ === How to start an authenticated session
68
+
69
+ The Megar::Session object is the main entry point for the library.
70
+ All requests on the Mega API are made in the context of an established session.
71
+
72
+ # create a session with immediate authentication
73
+ session = Megar::Session.new(email: 'my@email.com', password: 'my_password')
74
+
75
+ It's possible to delay the authentication
76
+
77
+ # create a session with deferred authentication
78
+ session = Megar::Session.new(email: 'my@email.com', password: 'my_password', autoconnect: false )
79
+ # then explicitly login:
80
+ session.connect!
81
+
82
+ === How to get a listing of all folders
83
+
84
+ Folders are accessed through an authenticated <tt>Megar::Session</tt> object.
85
+
86
+ all_folders = session.folders
87
+
88
+ <tt>folders</tt> is an enumerable collection, so you can iterate as you would expect:
89
+
90
+ session.folders.each do |folder|
91
+ puts folder.name
92
+ end
93
+
94
+ === How to get a handle to the special Mega folders
95
+
96
+ In addition to any folders you create yourself, Mega provides three standard folders:
97
+ root ("Cloud Drive"), inbox and trash. Shortcuts are available on the folders collection to
98
+ grab a handle on these directly:
99
+
100
+ my_folders = session.folders
101
+ my_folders.root
102
+ my_folders.inbox
103
+ my_folders.trash
104
+
105
+ === What are all the attributes of a folder?
106
+
107
+ Once you have a folder object (e.g. <tt>session.folders.first</tt>), the following are the
108
+ primary attributes it exposes:
109
+
110
+ * id: the unique ID, corresponds to the Mega node handle
111
+ * name: the name of the folder
112
+
113
+
114
+ === How to get a listing of all files in a folder
115
+
116
+ A folder node provides a files collection
117
+
118
+ session.folders.first.files.each do |file|
119
+ puts file.name
120
+ end
121
+
122
+
123
+ === How to get a listing of all files
124
+
125
+ All files can be accessed directly without needing to navigate via a folder object.
126
+
127
+ all_files = session.files
128
+
129
+ <tt>files</tt> is an enumerable collection, so you can iterate as you would expect:
130
+
131
+ session.files.each do |file|
132
+ puts file.id
133
+ puts file.name
134
+ puts file.size
135
+ end
136
+
137
+
138
+ === What are all the attributes of a file?
139
+
140
+ Once you have a file object (e.g. <tt>session.files.first</tt>), the following are the
141
+ primary attributes it exposes:
142
+
143
+ * id: the unique ID, corresponds to the Mega node handle
144
+ * name: the name of the file
145
+ * size: the size of the file content (in bytes)
146
+
147
+
148
+ === CLI: How to use the command-line client
149
+
150
+ The gem installation includes a command-line tool. Call it without parameters and it will show help:
151
+
152
+ $ megar
153
+
154
+ All operations require credentials to ba passed on the command line (email and password arguments):
155
+
156
+ $ megar --email=my@email.com --password=mypassword
157
+ Connecting to mega as my@email.com..
158
+ Connected!
159
+
160
+
161
+ === CLI: How to get a file listing
162
+
163
+ Use the <tt>ls</tt> command:
164
+
165
+ $ megar --email=my@email.com --password=mypassword ls
166
+ Connecting to mega as my@email.com..
167
+ 39 bytes 74ZTXbyR hello_mega.txt
168
+ 137080 bytes L0xHwayA mega.png
169
+
170
+
171
+ === How to run tests
172
+
173
+ Test are implemented using rspec. Run tests with <tt>rake</tt> or <tt>rake spec</tt>.
174
+
175
+ {Guard}[https://rubygems.org/gems/guard] is installed as part of the development dependencies,
176
+ so to start continuous test execution on file change, start it up with <tt>bundle exec guard</tt>.
177
+
178
+
179
+ === How to refresh unit test expectations
180
+
181
+ Unit tests make liberal use of expected responses from the actual Mega API.
182
+ In order to enable good unit tests without hitting the Mega API for real,
183
+ test expectations are stored as JSON under 'spec/fixtures/crypto_expectations'.
184
+
185
+ A rake task is available to re-generate the expectations:
186
+
187
+ $ rake gen:crypto_expectations email=my@email.com password=mypassword
188
+
189
+ Generating crypto_expectations for my@email.com...
190
+
191
+ Done! New crypto_expectations for unit test written to:
192
+ /.../megar/spec/fixtures/crypto_expectations/sample_user.json
193
+
194
+ NOTE: the email and password are stored in the expectations file, so be careful not to
195
+ commit and distribute credentials. Change the password on the account first.
196
+ The tests will still run as intended with the snapshot of crypto details stored in the expectations file.
197
+
198
+
199
+ == References
200
+
201
+ * {Mega API is documentation}[https://mega.co.nz/#developers]
202
+ * {Using the Mega API, with Python examples}[http://julien-marchand.fr/blog/using-mega-api-with-python-examples/]
203
+ * {SpiderOak's Analysis and Recommendations for the Crypto in Kim Dotcom's Mega}[https://spideroak.com/blog/20130123130638-spideroaks-analysis-and-recommendations-for-the-crypto-in-kim-dotcoms-mega-part-one]
204
+
205
+
206
+ == Contributing
207
+
208
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
209
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
210
+ * Fork the project
211
+ * Start a feature/bugfix branch
212
+ * Commit and push until you are happy with your contribution
213
+ * Make sure to add tests for it. This is important so it doesn't get broken in a future version unintentionally.
214
+ * Please try not to mess with the gemspec, Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so it can be cherry-picked around.
215
+
216
+ == Copyright
217
+
218
+ Copyright (c) 2013 Paul Gallagher. See LICENSE for further details.
data/Rakefile ADDED
@@ -0,0 +1,33 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec'
3
+ require 'rspec/core/rake_task'
4
+
5
+ desc "Run all test examples"
6
+ RSpec::Core::RakeTask.new do |t|
7
+ t.rspec_opts = ["-c", "-f progress"]
8
+ t.pattern = 'spec/**/*_spec.rb'
9
+ end
10
+
11
+ task :default => :spec
12
+
13
+ require 'rdoc/task'
14
+ RDoc::Task.new do |rdoc|
15
+ rdoc.main = "README.md"
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = "megar"
18
+ rdoc.rdoc_files.include('README*', 'lib/**/*.rb')
19
+ end
20
+
21
+ desc "Open an irb session preloaded with this library"
22
+ task :console do
23
+ sh "irb -rubygems -I lib -r megar.rb"
24
+ end
25
+
26
+ namespace :gen do
27
+ desc "Generate new unit test expectations given email=your_email password=your_password"
28
+ task :crypto_expectations do
29
+ require './spec/spec_helper.rb'
30
+ include CryptoExpectationsHelper
31
+ generate_crypto_expectations(ENV['email'], ENV['password'])
32
+ end
33
+ end
data/bin/megar ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
+
4
+ require 'megar'
5
+ require 'getoptions'
6
+
7
+ begin
8
+ options = GetOptions.new(Megar::Shell::OPTIONS)
9
+ Megar::Shell.new(options,ARGV).run
10
+ rescue Interrupt
11
+ $stderr.puts "..interrupted."
12
+ rescue Exception => e
13
+ $stderr.puts "That wasn't meant to happen! #{e.message}"
14
+ Megar::Shell.usage
15
+ end
16
+
@@ -0,0 +1,13 @@
1
+
2
+ # Calculate ((b**p) % m) assuming that b and m are large integers.
3
+ # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/71964
4
+ def Math.powm(b, p, m)
5
+ if p == 1
6
+ b % m
7
+ elsif (p & 0x1) == 0 # p.even?
8
+ t = powm(b, p >> 1, m)
9
+ (t * t) % m
10
+ else
11
+ (b * powm(b, p-1, m)) % m
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ Mega API Javascript Refeence Implementation
2
+
3
+ The files contained in this folder are not used by the Megar gem.
4
+
5
+ These are the source Javascript files obtained from mega.co.nz in the course of megar development,
6
+ and are only stored here to provide some traceability when the javascript implementation changes.
7
+ This is only important while the Javascript implementation is the only concrete reference to details
8
+ of the Mega API. It will become redundant when the Mega API is formally lanched with detailed
9
+ documentation.
@@ -0,0 +1,83 @@
1
+
2
+ /* OpenPGP radix-64/base64 string encoding/decoding
3
+ * Copyright 2005 Herbert Hanewinkel, www.haneWIN.de
4
+ * version 1.0, check www.haneWIN.de for the latest version
5
+
6
+ * This software is provided as-is, without express or implied warranty.
7
+ * Permission to use, copy, modify, distribute or sell this software, with or
8
+ * without fee, for any purpose and by any individual or organization, is hereby
9
+ * granted, provided that the above copyright notice and this paragraph appear
10
+ * in all copies. Distribution as a part of an application or binary must
11
+ * include the above copyright notice in the documentation and/or other materials
12
+ * provided with the application or distribution.
13
+ */
14
+
15
+ var b64s='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
16
+
17
+ function s2r(t)
18
+ {
19
+ var a, c, n;
20
+ var r='', l=0, s=0;
21
+ var tl=t.length;
22
+
23
+ for(n=0; n<tl; n++)
24
+ {
25
+ c=t.charCodeAt(n);
26
+ if(s == 0)
27
+ {
28
+ r+=b64s.charAt((c>>2)&63);
29
+ a=(c&3)<<4;
30
+ }
31
+ else if(s==1)
32
+ {
33
+ r+=b64s.charAt((a|(c>>4)&15));
34
+ a=(c&15)<<2;
35
+ }
36
+ else if(s==2)
37
+ {
38
+ r+=b64s.charAt(a|((c>>6)&3));
39
+ l+=1;
40
+ if((l%60)==0) r+="\n";
41
+ r+=b64s.charAt(c&63);
42
+ }
43
+ l+=1;
44
+ if((l%60)==0) r+="\n";
45
+
46
+ s+=1;
47
+ if(s==3) s=0;
48
+ }
49
+ if(s>0)
50
+ {
51
+ r+=b64s.charAt(a);
52
+ l+=1;
53
+ if((l%60)==0) r+="\n";
54
+ r+='=';
55
+ l+=1;
56
+ }
57
+ if(s==1)
58
+ {
59
+ if((l%60)==0) r+="\n";
60
+ r+='=';
61
+ }
62
+
63
+ return r;
64
+ }
65
+
66
+ function r2s(t)
67
+ {
68
+ var c, n;
69
+ var r='', s=0, a=0;
70
+ var tl=t.length;
71
+
72
+ for(n=0; n<tl; n++)
73
+ {
74
+ c=b64s.indexOf(t.charAt(n));
75
+ if(c >= 0)
76
+ {
77
+ if(s) r+=String.fromCharCode(a | (c>>(6-s))&255);
78
+ s=(s+2)&7;
79
+ a=(c<<s)&255;
80
+ }
81
+ }
82
+ return r;
83
+ }