cloud_door 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.travis.yml +4 -0
  4. data/Gemfile +4 -0
  5. data/Guardfile +7 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +204 -0
  8. data/Rakefile +11 -0
  9. data/bin/dropbox +133 -0
  10. data/bin/onedrive +133 -0
  11. data/cloud_door.gemspec +38 -0
  12. data/cloud_door_config.yml +12 -0
  13. data/data/.gitkeep +0 -0
  14. data/data/testlist +0 -0
  15. data/lib/cloud_door.rb +114 -0
  16. data/lib/cloud_door/account.rb +27 -0
  17. data/lib/cloud_door/cloud_storage.rb +294 -0
  18. data/lib/cloud_door/cloud_yaml.rb +45 -0
  19. data/lib/cloud_door/config.rb +61 -0
  20. data/lib/cloud_door/console.rb +334 -0
  21. data/lib/cloud_door/dropbox.rb +166 -0
  22. data/lib/cloud_door/exceptions.rb +153 -0
  23. data/lib/cloud_door/file_list.rb +164 -0
  24. data/lib/cloud_door/onedrive.rb +180 -0
  25. data/lib/cloud_door/onedrive_api.rb +169 -0
  26. data/lib/cloud_door/token.rb +67 -0
  27. data/lib/cloud_door/version.rb +3 -0
  28. data/log/.gitkeep +0 -0
  29. data/spec/cloud_door/account_spec.rb +96 -0
  30. data/spec/cloud_door/cloud_storage_spec.rb +10 -0
  31. data/spec/cloud_door/cloud_yaml_spec.rb +32 -0
  32. data/spec/cloud_door/config_spec.rb +95 -0
  33. data/spec/cloud_door/console_spec.rb +633 -0
  34. data/spec/cloud_door/dropbox_spec.rb +625 -0
  35. data/spec/cloud_door/file_list_spec.rb +451 -0
  36. data/spec/cloud_door/onedrive_api_spec.rb +256 -0
  37. data/spec/cloud_door/onedrive_spec.rb +652 -0
  38. data/spec/cloud_door/token_spec.rb +81 -0
  39. data/spec/fabricators/account_fabricator.rb +5 -0
  40. data/spec/fabricators/cloud_yaml_fabricator.rb +5 -0
  41. data/spec/fabricators/config_fabrication.rb +5 -0
  42. data/spec/fabricators/token_fabricator.rb +10 -0
  43. data/spec/spec_helper.rb +55 -0
  44. metadata +380 -0
@@ -0,0 +1,169 @@
1
+ require 'logger'
2
+ require 'open-uri'
3
+ require 'rest_client'
4
+
5
+ module CloudDoor
6
+ class OneDriveApi
7
+ attr_accessor :access_token
8
+
9
+ # domain for auth
10
+ AUTH_BASE = 'https://login.live.com/'
11
+ # URL for auth
12
+ AUTH_FORMAT = AUTH_BASE +
13
+ 'oauth20_authorize.srf?client_id=%s&scope=%s&response_type=code&redirect_uri=%s'
14
+ # URL for get token
15
+ TOKEN_URL = AUTH_BASE + 'oauth20_token.srf'
16
+ # domain for action
17
+ ACTION_BASE = 'https://apis.live.net/v5.0/'
18
+ # URL for get user info
19
+ USER_FORMAT = ACTION_BASE + 'me?access_token=%s'
20
+ # URL for get directory
21
+ DIR_FORMAT = ACTION_BASE + '%s/files?access_token=%s'
22
+ # URL for get file info
23
+ FILE_FORMAT = ACTION_BASE + '%s?access_token=%s'
24
+ # URL for download file
25
+ DOWNLOAD_FORMAT = ACTION_BASE + '%s/content?suppress_redirects=true&access_token=%s'
26
+ # URL for upload file
27
+ UPLOAD_FORMAT = ACTION_BASE + '%s/files?access_token=%s'
28
+ # URL for delete file
29
+ DELETE_FORMAT = ACTION_BASE + '%s?access_token=%s'
30
+ # URL for make directory
31
+ MKDIR_FORMAT = ACTION_BASE + '%s'
32
+ # update scope
33
+ UPDATE_SCOPE = 'wl.skydrive_update,wl.offline_access'
34
+ # log_file
35
+ LOG_FILE = './log/request.log'
36
+
37
+ def initialize(access_token)
38
+ @access_token = access_token
39
+ end
40
+
41
+ def request_get_token(code, client_id, client_secret, redirect_url)
42
+ post_body = {
43
+ client_id: client_id,
44
+ client_secret: client_secret,
45
+ redirect_uri: redirect_url,
46
+ code: code,
47
+ grant_type: 'authorization_code'
48
+ }
49
+ header = {content_type: 'application/x-www-form-urlencoded'}
50
+ send_request(:post, TOKEN_URL, post_body, header)
51
+ end
52
+
53
+ def request_refresh_token(refresh_token, client_id, client_secret, redirect_url)
54
+ post_body = {
55
+ client_id: client_id,
56
+ client_secret: client_secret,
57
+ redirect_uri: redirect_url,
58
+ grant_type: 'refresh_token',
59
+ refresh_token: refresh_token
60
+ }
61
+ header = {content_type: 'application/x-www-form-urlencoded'}
62
+ send_request(:post, TOKEN_URL, post_body, header)
63
+ end
64
+
65
+ def request_user
66
+ url = USER_FORMAT % @access_token
67
+ send_request(:get, url)
68
+ end
69
+
70
+ def request_dir(file_id)
71
+ url = DIR_FORMAT % [file_id, @access_token]
72
+ send_request(:get, url)
73
+ end
74
+
75
+ def request_file(file_id)
76
+ url = FILE_FORMAT % [file_id, @access_token]
77
+ send_request(:get, url)
78
+ end
79
+
80
+ def request_download(file_id)
81
+ url = DOWNLOAD_FORMAT % [file_id, @access_token]
82
+ info = send_request(:get, url)
83
+ key = 'location'
84
+ raise NoDataException if info.nil? || !info.is_a?(Hash) || !info.key?(key)
85
+ file_url = info[key]
86
+ open(file_url).read
87
+ end
88
+
89
+ def request_upload(file_path, parent_id)
90
+ url = UPLOAD_FORMAT % [parent_id, @access_token]
91
+ send_request(:post_file, url, File.new(file_path, 'rb'))
92
+ end
93
+
94
+ def request_delete(file_id)
95
+ url = DELETE_FORMAT % [file_id, @access_token]
96
+ send_request(:delete, url)
97
+ end
98
+
99
+ def request_mkdir(name, parent_id)
100
+ url = MKDIR_FORMAT % parent_id
101
+ body = JSON('name' => name)
102
+ header = {
103
+ 'Authorization' => "Bearer #{@access_token}",
104
+ 'Content-Type' => 'application/json'
105
+ }
106
+ send_request(:post, url, body, header)
107
+ end
108
+
109
+ class << self
110
+ def make_auth_url(client_id, redirect_url)
111
+ AUTH_FORMAT % [client_id, UPDATE_SCOPE, redirect_url]
112
+ end
113
+ end
114
+
115
+ private
116
+
117
+ def send_request(method, url, body = '', header = {})
118
+ # if method == :get
119
+ # res = RestClient.get(url) do |response, request, result|
120
+ # request_log(response, request, result)
121
+ # response
122
+ # end
123
+ # elsif method == :post
124
+ # res = RestClient.post(url, body, header) do |response, request, result|
125
+ # request_log(response, request, result)
126
+ # response
127
+ # end
128
+ # elsif method == :delete
129
+ # res = RestClient.delete(url) do |response, request, result|
130
+ # request_log(response, request, result)
131
+ # response
132
+ # end
133
+ # elsif method == :post_file
134
+ # res = RestClient.post(url, :file => body) do |response, request, result|
135
+ # request_log(response, request, result)
136
+ # response
137
+ # end
138
+ # end
139
+ if method == :get
140
+ res = RestClient.get(url)
141
+ elsif method == :post
142
+ res = RestClient.post(url, body, header)
143
+ elsif method == :delete
144
+ res = RestClient.delete(url)
145
+ elsif method == :post_file
146
+ res = RestClient.post(url, file: body)
147
+ end
148
+ # raise NoDataException if res.body.nil? || res.body.empty?
149
+ return if res.body.nil? || res.body.empty?
150
+ JSON.parse(res.body)
151
+ rescue => e
152
+ if e.is_a?(RestClient::Unauthorized)
153
+ raise UnauthorizedException
154
+ elsif e.class.to_s.include?('RestClient')
155
+ raise HttpConnectionException
156
+ else
157
+ raise
158
+ end
159
+ end
160
+
161
+ def request_log(response, request, result)
162
+ logger = Logger.new(LOG_FILE)
163
+ log = "request:\n#{request.args.inspect}\n"
164
+ log << "result:\n#{result.inspect}\n"
165
+ log << "response:\n#{JSON.parse(response.body).inspect}\n"
166
+ logger.info(log)
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,67 @@
1
+ module CloudDoor
2
+ class Token
3
+ attr_accessor :token_file, :token_type, :expires_in, :scope, :access_token,
4
+ :refresh_token, :user_id, :token_name
5
+ attr_reader :data_path
6
+
7
+ TOKEN_ITEMS = [
8
+ 'token_type',
9
+ 'expires_in',
10
+ 'scope',
11
+ 'access_token',
12
+ 'refresh_token',
13
+ 'user_id'
14
+ ]
15
+
16
+ def initialize(token_name, data_path, id = nil)
17
+ @token_name = token_name
18
+ @data_path = data_path
19
+ if id.nil?
20
+ @token_file = @data_path + @token_name
21
+ else
22
+ token_dir = @data_path + "#{id}"
23
+ unless File.exists?(token_dir)
24
+ Dir.mkdir(token_dir)
25
+ end
26
+ @token_file = "#{token_dir}/#{@token_name}"
27
+ end
28
+ end
29
+
30
+ def set_locate(id)
31
+ token_dir = @data_path + "#{id}"
32
+ unless File.exists?(token_dir)
33
+ Dir.mkdir(token_dir)
34
+ end
35
+ @token_file = "#{token_dir}/#{@token_name}"
36
+ end
37
+
38
+ def set_attributes(attributes)
39
+ TOKEN_ITEMS.each do |item|
40
+ instance_variable_set("@#{item}", attributes[item]) if attributes.key?(item)
41
+ end
42
+ end
43
+
44
+ def write_token
45
+ marshal = Marshal.dump(self)
46
+ open(@token_file, 'wb') { |file| file << marshal }
47
+ true
48
+ rescue
49
+ false
50
+ end
51
+
52
+ def self.load_token(token_name, data_path, id = nil)
53
+ if id.nil?
54
+ token_file = data_path + token_name
55
+ else
56
+ token_file = data_path + "#{id}/#{token_name}"
57
+ end
58
+ return nil unless File.exist?(token_file)
59
+ marshal = File.open(token_file).read
60
+ token = Marshal.load(marshal)
61
+ return nil unless token.is_a?(Token)
62
+ token
63
+ rescue
64
+ nil
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,3 @@
1
+ module CloudDoor
2
+ VERSION = "0.0.1"
3
+ end
File without changes
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Account' do
4
+ let(:account_file) { './data/test.yml' }
5
+ describe 'isset_account?' do
6
+ subject { account.isset_account? }
7
+ let(:account) { Fabricate.build(:account, storage: 'onedrive', file: account_file) }
8
+ context 'account & password setted' do
9
+ before(:each) do
10
+ account.login_account = 'login@onedrive.com'
11
+ account.login_password = 'onedrive.com'
12
+ end
13
+ it { is_expected.to be_truthy }
14
+ end
15
+ context 'account not setted' do
16
+ before(:each) do
17
+ account.login_account = 'login@onedrive.com'
18
+ account.login_password = ''
19
+ end
20
+ it { is_expected.to be_falsey }
21
+ end
22
+ context 'password not setted' do
23
+ before(:each) do
24
+ account.login_account = ''
25
+ account.login_password = 'onedrive.com'
26
+ end
27
+ it { is_expected.to be_falsey }
28
+ end
29
+ end
30
+
31
+ describe 'load_yaml' do
32
+ before(:all) do
33
+ accounts = {
34
+ 'onedrive' => {
35
+ 'login_account' => 'login@onedrive.com',
36
+ 'login_password' => 'onedrive'
37
+ },
38
+ 'dropbox' => {
39
+ 'login_account' => 'login@dropbox.com',
40
+ 'login_password' => 'dropbox'
41
+ }
42
+ }
43
+ open('./data/test.yml', 'wb') { |file| YAML.dump(accounts, file) }
44
+ end
45
+ before(:each) { account.load_yaml }
46
+ context 'onedrive' do
47
+ let(:account) { Fabricate.build(:account, storage: 'onedrive', file: account_file) }
48
+ it { expect(account.login_account).to eq 'login@onedrive.com' }
49
+ it { expect(account.login_password).to eq 'onedrive' }
50
+ end
51
+ context 'dropbox' do
52
+ let(:account) { Fabricate.build(:account, storage: 'dropbox', file: account_file) }
53
+ it { expect(account.login_account).to eq 'login@dropbox.com' }
54
+ it { expect(account.login_password).to eq 'dropbox' }
55
+ end
56
+ after(:all) do
57
+ File.delete('./data/test.yml') if File.exist?('./data/test.yml')
58
+ end
59
+ end
60
+
61
+ describe 'update_yaml' do
62
+ before(:each) do
63
+ File.delete(account_file) if File.exist?(account_file)
64
+ account.update_yaml(update_params)
65
+ end
66
+ context 'onedrive' do
67
+ let(:account) { Fabricate.build(:account, storage: 'onedrive', file: account_file) }
68
+ let(:update_params) do
69
+ {
70
+ 'login_account' => 'login@onedrive.com',
71
+ 'login_password' => 'onedrive'
72
+ }
73
+ end
74
+ let(:load_file) { YAML.load_file(account_file)['onedrive'] }
75
+ it { expect(File.exist?(account_file)).to be_truthy }
76
+ it { expect(load_file['login_account']).to eq 'login@onedrive.com' }
77
+ it { expect(load_file['login_password']).to eq 'onedrive' }
78
+ end
79
+ context 'dropbox' do
80
+ let(:account) { Fabricate.build(:account, storage: 'dropbox', file: account_file) }
81
+ let(:update_params) do
82
+ {
83
+ 'login_account' => 'login@dropbox.com',
84
+ 'login_password' => 'dropbox'
85
+ }
86
+ end
87
+ let(:load_file) { YAML.load_file(account_file)['dropbox'] }
88
+ it { expect(File.exist?(account_file)).to be_truthy }
89
+ it { expect(load_file['login_account']).to eq 'login@dropbox.com' }
90
+ it { expect(load_file['login_password']).to eq 'dropbox' }
91
+ end
92
+ after(:each) do
93
+ File.delete(account_file) if File.exist?(account_file)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ # CloudStorage class is abstract class.
4
+ # then, test inherited subclass.
5
+ describe 'CloudStorage' do
6
+ describe 'initialize' do
7
+ subject { CloudDoor::CloudStorage.new }
8
+ it { expect { subject }.to raise_error(CloudDoor::AbstractClassException) }
9
+ end
10
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'CloudYaml' do
4
+ describe 'load_yaml' do
5
+ subject { account.load_yaml }
6
+ account_file = './data/test.yml'
7
+ before(:all) do
8
+ accounts = {
9
+ 'onedrive' => {
10
+ 'login_account' => 'login@onedrive.com',
11
+ 'login_password' => 'onedrive'
12
+ }
13
+ }
14
+ open(account_file, 'wb') { |file| YAML.dump(accounts, file) }
15
+ end
16
+ context 'file & storage exists' do
17
+ let(:account) { Fabricate.build(:cloud_yaml, file: account_file) }
18
+ it { is_expected.to be_truthy }
19
+ end
20
+ context 'file not exists' do
21
+ let(:account) { Fabricate.build(:cloud_yaml, file: './data/example.yml') }
22
+ it { is_expected.to be_falsey }
23
+ end
24
+ context 'storage exists' do
25
+ let(:account) { Fabricate.build(:cloud_yaml, file: account_file, storage: 'example') }
26
+ it { is_expected.to be_falsey }
27
+ end
28
+ after(:all) do
29
+ File.delete(account_file) if File.exist?(account_file)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Config' do
4
+ describe 'load_yaml' do
5
+ let(:config_file) { './data/test.yml' }
6
+ before(:all) do
7
+ configs = {
8
+ 'onedrive' => {
9
+ 'client_id' => '1234',
10
+ 'client_secret' => 'abcd',
11
+ 'redirect_url' => 'onedrive'
12
+ },
13
+ 'dropbox' => {
14
+ 'client_id' => '5678',
15
+ 'client_secret' => 'efgh',
16
+ 'redirect_url' => 'dropbox'
17
+ }
18
+ }
19
+ open('./data/test.yml', 'wb') { |file| YAML.dump(configs, file) }
20
+ end
21
+ before(:each) { config.load_yaml }
22
+ context 'onedrive' do
23
+ let(:config) { Fabricate.build(:config, storage: 'onedrive', file: config_file) }
24
+ it { expect(config.client_id).to eq '1234' }
25
+ it { expect(config.client_secret).to eq 'abcd' }
26
+ it { expect(config.redirect_url).to eq 'onedrive' }
27
+ end
28
+ context 'dropbox' do
29
+ let(:config) { Fabricate.build(:config, storage: 'dropbox', file: config_file) }
30
+ it { expect(config.client_id).to eq '5678' }
31
+ it { expect(config.client_secret).to eq 'efgh' }
32
+ it { expect(config.redirect_url).to eq 'dropbox' }
33
+ end
34
+ after(:all) do
35
+ File.delete('./data/test.yml') if File.exist?('./data/test.yml')
36
+ end
37
+ end
38
+
39
+ describe 'update_yaml' do
40
+ let(:config_file) { './data/test.yml' }
41
+ before(:each) do
42
+ File.delete(config_file) if File.exist?(config_file)
43
+ account.update_yaml(update_params)
44
+ end
45
+ context 'onedrive' do
46
+ let(:account) { Fabricate.build(:config, storage: 'onedrive', file: config_file) }
47
+ let(:update_params) do
48
+ {
49
+ 'client_id' => '1234',
50
+ 'client_secret' => 'abcd',
51
+ 'redirect_url' => 'onedrive'
52
+ }
53
+ end
54
+ let(:load_file) { YAML.load_file(config_file)['onedrive'] }
55
+ it { expect(File.exist?(config_file)).to be_truthy }
56
+ it { expect(load_file['client_id']).to eq '1234' }
57
+ it { expect(load_file['client_secret']).to eq 'abcd' }
58
+ it { expect(load_file['redirect_url']).to eq 'onedrive' }
59
+ end
60
+ context 'dropbox' do
61
+ let(:account) { Fabricate.build(:config, storage: 'dropbox', file: config_file) }
62
+ let(:update_params) do
63
+ {
64
+ 'client_id' => '5678',
65
+ 'client_secret' => 'efgh',
66
+ 'redirect_url' => 'dropbox'
67
+ }
68
+ end
69
+ let(:load_file) { YAML.load_file(config_file)['dropbox'] }
70
+ it { expect(File.exist?(config_file)).to be_truthy }
71
+ it { expect(load_file['client_id']).to eq '5678' }
72
+ it { expect(load_file['client_secret']).to eq 'efgh' }
73
+ it { expect(load_file['redirect_url']).to eq 'dropbox' }
74
+ end
75
+ after(:each) do
76
+ File.delete(config_file) if File.exist?(config_file)
77
+ end
78
+ end
79
+
80
+ describe 'init?' do
81
+ subject { config.init? }
82
+ let(:config) { Fabricate.build(:config) }
83
+ context 'initialized' do
84
+ before(:each) do
85
+ config.client_id = '1234'
86
+ config.client_secret = 'abcd'
87
+ config.redirect_url = 'onedrive'
88
+ end
89
+ it { is_expected.to be_truthy }
90
+ end
91
+ context 'not initialized' do
92
+ it { is_expected.to be_falsey }
93
+ end
94
+ end
95
+ end