boxr 0.0.3 → 0.1.0

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: 67e27a5d8aa317d4f5367ca297a6effba37f940c
4
- data.tar.gz: b3541ffde249148cbdde2f1666479c1377993b7e
3
+ metadata.gz: 85a9e52479cab2e593a06741ba16b2e4a44f60d6
4
+ data.tar.gz: 20e2668309a30f3adbd07a0f494ccb97788144a0
5
5
  SHA512:
6
- metadata.gz: 9837ce765c7cf63b3df57ab8fbf513b2e9f6745d447291bcedfd7a9bdc672028b185b93b52797c1fc9e36600f931fe6f40f0824122f659eff96ca052d3a3ae0d
7
- data.tar.gz: bd84a9467ad8df991be52c8832cd63e0e5bb112352e20d7d1418b3ad7ddc77d98d4dbbb6c71eee253eeeb5d70a926fe10b4d1188ec4ec7df45c31aad7d536e01
6
+ metadata.gz: 46f24ca8c3bfb93a098c5dfbd63b69eeff3a316e662d119d096a0c92264608d755629fe933955d9ab5ad7b78d960c870ffb05bcc6427ee9bc78e1dda7568ca30
7
+ data.tar.gz: 7f62b487fe1526578ab85386dda281b6cabcf1f21a69fcc83b39cd469dc7109b060dea139a4775016e2f060269045b2641bff38dfcc144478335b7939f08d274
@@ -3,7 +3,10 @@
3
3
  #3. click 'Edit Application'
4
4
  #4. check the boxes for 'Read and write all files and folders' and 'Manage an enterprise'
5
5
  #5. click 'Create a developer token'
6
- #6. paste the value below
7
- #7. save this file as .env
6
+ #6. copy and paste the developer token below
7
+ #7. copy and paste the client id and client secret of your Box app below
8
+ #8. save this file as .env
8
9
 
9
- BOX_DEVELOPER_TOKEN=bsuwpLRJYN123NJTOisOvdvBCloboMqW
10
+ BOX_DEVELOPER_TOKEN={a valid developer token for your Box app}
11
+ BOX_CLIENT_ID={client id of your Box app}
12
+ BOX_CLIENT_SECRET={client secret of your Box app}
data/Rakefile CHANGED
@@ -1,5 +1,3 @@
1
- import "./lib/tasks/oauth.rake"
2
-
3
1
  require 'rspec/core/rake_task'
4
2
  require "bundler/gem_tasks"
5
3
 
@@ -5,17 +5,17 @@ require 'awesome_print'
5
5
  client = Boxr::Client.new(ENV['BOX_DEVELOPER_TOKEN'])
6
6
 
7
7
  now = Time.now
8
- start_date = now - (60*60*24*30) #three days ago
9
- end_date = now - (60*60*24) #one day ago
8
+ start_date = now - (60*60*24) #one day ago
9
+ end_date = now
10
10
 
11
11
  stream_position = 0
12
12
  puts "fetching enterprise events..."
13
13
  loop do
14
- event_response = client.enterprise_events(stream_position: stream_position, created_after: start_date.utc, created_before: end_date.utc)
15
- event_response.events.each do |event|
16
- ap event
17
- end
18
- stream_position = event_response.next_stream_position
14
+ event_response = client.enterprise_events(stream_position: stream_position, created_after: start_date.utc, created_before: end_date.utc)
15
+ event_response.events.each do |event|
16
+ puts "#{event.event_type}, #{event.created_by.name}"
17
+ end
18
+ stream_position = event_response.next_stream_position
19
19
 
20
- break if event_response.events.empty?
20
+ break if event_response.events.empty?
21
21
  end
@@ -0,0 +1,27 @@
1
+ require 'dotenv'; Dotenv.load("../.env")
2
+ require 'boxr'
3
+ require 'uri'
4
+ require 'awesome_print'
5
+
6
+ #make sure you have BOX_CLIENT_ID and BOX_CLIENT_SECRET set in your .env file
7
+ #make sure you have the redirect_uri for your application set to something like https://localhost:1234 in the developer portal
8
+
9
+ oauth_url = Boxr::oauth_url(URI.encode_www_form_component('your-anti-forgery-token'))
10
+
11
+ puts "Copy the URL below and paste into a browser. Go through the OAuth flow using the desired Box account. \
12
+ When you are finished your browser will redirect to a 404 error page. This is expected behavior. Look at the URL in the address \
13
+ bar and copy the 'code' parameter value. Paste it into the prompt below. You only have 30 seconds to complete this task so be quick about it! \
14
+ You will then see your access token and refresh token."
15
+
16
+ puts
17
+ puts "URL: #{oauth_url}"
18
+ puts
19
+
20
+ print "Enter the code: "
21
+ code = STDIN.gets.chomp.split('=').last
22
+
23
+ ap Boxr::get_tokens(code)
24
+
25
+
26
+
27
+
@@ -8,17 +8,17 @@ cache = LruRedux::Cache.new(1000)
8
8
 
9
9
  stream_position = :now
10
10
  loop do
11
- puts "fetching events..."
12
- event_response = client.user_events(stream_position: stream_position)
13
- event_response.events.each do |event|
14
- key = "/box-event/id/#{event.event_id}"
11
+ puts "fetching events..."
12
+ event_response = client.user_events(stream_position: stream_position)
13
+ event_response.events.each do |event|
14
+ key = "/box-event/id/#{event.event_id}"
15
15
 
16
- #we need to de-dupe the events because we will receive multiple events with the same event_id; this is to ensure that we get the event
17
- if (cache.fetch(event.event_id)==nil)
18
- cache[event.event_id] = true
19
- puts event.event_type
20
- end
21
- end
22
- stream_position = event_response.next_stream_position
23
- sleep 2
16
+ #we need to de-dupe the events because we will receive multiple events with the same event_id; this is to ensure that we get the event
17
+ if (cache.fetch(event.event_id)==nil)
18
+ cache[event.event_id] = true
19
+ puts event.event_type
20
+ end
21
+ end
22
+ stream_position = event_response.next_stream_position
23
+ sleep 2
24
24
  end
@@ -16,24 +16,25 @@ require 'boxr/search'
16
16
  require 'boxr/tasks'
17
17
  require 'boxr/metadata'
18
18
  require 'boxr/events'
19
+ require 'boxr/auth'
19
20
 
20
21
  module Enumerable
21
- def files
22
- self.select{|i| i.type == 'file'}
23
- end
22
+ def files
23
+ self.select{|i| i.type == 'file'}
24
+ end
24
25
 
25
- def folders
26
- self.select{|i| i.type == 'folder'}
27
- end
26
+ def folders
27
+ self.select{|i| i.type == 'folder'}
28
+ end
28
29
 
29
- def web_links
30
- self.select{|i| i.type == 'web_link'}
31
- end
30
+ def web_links
31
+ self.select{|i| i.type == 'web_link'}
32
+ end
32
33
  end
33
34
 
34
35
  module Boxr
35
36
  Oj.default_options = {:mode => :compat }
36
37
 
37
- #The root folder in Box is always identified by 0
38
- ROOT = 0
38
+ #The root folder in Box is always identified by 0
39
+ ROOT = 0
39
40
  end
@@ -0,0 +1,46 @@
1
+ module Boxr
2
+
3
+ def self.oauth_url(state, response_type: "code", scope: nil, folder_id: nil, box_client_id: ENV['BOX_CLIENT_ID'])
4
+ uri = "https://app.box.com/api/oauth2/authorize?response_type=#{response_type}&state=#{state}&client_id=#{box_client_id}"
5
+ uri = uri + "&scope=#{scope}" unless scope.nil?
6
+ uri = uri + "&folder_id=#{folder_id}" unless folder_id.nil?
7
+ uri
8
+ end
9
+
10
+ def self.get_tokens(code, grant_type: "authorization_code", username: nil, box_client_id: ENV['BOX_CLIENT_ID'], box_client_secret: ENV['BOX_CLIENT_SECRET'])
11
+ uri = "https://api.box.com/oauth2/token"
12
+ body = "code=#{code}&grant_type=#{grant_type}&client_id=#{box_client_id}&client_secret=#{box_client_secret}"
13
+ body = body + "&username=#{username}" unless username.nil?
14
+
15
+ auth_post(uri, body)
16
+ end
17
+
18
+ def self.refresh_tokens(refresh_token, box_client_id: ENV['BOX_CLIENT_ID'], box_client_secret: ENV['BOX_CLIENT_SECRET'])
19
+ uri = "https://api.box.com/oauth2/token"
20
+ body = "grant_type=refresh_token&refresh_token=#{refresh_token}&client_id=#{box_client_id}&client_secret=#{box_client_secret}"
21
+
22
+ auth_post(uri, body)
23
+ end
24
+
25
+ def self.revoke_tokens(token, box_client_id: ENV['BOX_CLIENT_ID'], box_client_secret: ENV['BOX_CLIENT_SECRET'])
26
+ uri = "https://api.box.com/oauth2/revoke"
27
+ body = "client_id=#{box_client_id}&client_secret=#{box_client_secret}&token=#{token}"
28
+
29
+ auth_post(uri, body)
30
+ end
31
+
32
+ private
33
+
34
+ def self.auth_post(uri, body)
35
+ client = HTTPClient.new
36
+ res = client.post(uri, body: body)
37
+
38
+ if(res.status==200)
39
+ body_json = Oj.load(res.body)
40
+ return Hashie::Mash.new(body_json)
41
+ else
42
+ raise BoxrException.new(status: res.status, body: res.body, header: res.header)
43
+ end
44
+ end
45
+
46
+ end
@@ -1,217 +1,258 @@
1
1
  module Boxr
2
-
3
- class Client
4
-
5
- API_URI = "https://api.box.com/2.0"
6
- UPLOAD_URI = "https://upload.box.com/api/2.0"
7
- FILES_URI = "#{API_URI}/files"
8
- FILES_UPLOAD_URI = "#{UPLOAD_URI}/files/content"
9
- FOLDERS_URI = "#{API_URI}/folders"
10
- USERS_URI = "#{API_URI}/users"
11
- GROUPS_URI = "#{API_URI}/groups"
12
- GROUP_MEMBERSHIPS_URI = "#{API_URI}/group_memberships"
13
- COLLABORATIONS_URI = "#{API_URI}/collaborations"
14
- COMMENTS_URI = "#{API_URI}/comments"
15
- SEARCH_URI = "#{API_URI}/search"
16
- TASKS_URI = "#{API_URI}/tasks"
17
- TASK_ASSIGNMENTS_URI = "#{API_URI}/task_assignments"
18
- SHARED_ITEMS_URI = "#{API_URI}/shared_items"
19
- METADATA_URI = "#{API_URI}/files"
20
- EVENTS_URI = "#{API_URI}/events"
21
-
22
- DEFAULT_LIMIT = 100
23
- FOLDER_ITEMS_LIMIT = 1000
24
-
25
- FOLDER_AND_FILE_FIELDS = [:type,:id,:sequence_id,:etag,:name,:created_at,:modified_at,:description,
26
- :size,:path_collection,:created_by,:modified_by,:trashed_at,:purged_at,
27
- :content_created_at,:content_modified_at,:owned_by,:shared_link,:folder_upload_email,
28
- :parent,:item_status,:item_collection,:sync_state,:has_collaborations,:permissions,:tags,
29
- :sha1,:shared_link,:version_number,:comment_count,:lock,:extension,:is_package,:can_non_owners_invite]
30
- FOLDER_AND_FILE_FIELDS_QUERY = FOLDER_AND_FILE_FIELDS.join(',')
31
-
32
- COMMENT_FIELDS = [:type,:id,:is_reply_comment,:message,:tagged_message,:created_by,:created_at,:item,:modified_at]
33
- COMMENT_FIELDS_QUERY = COMMENT_FIELDS.join(',')
34
-
35
- TASK_FIELDS = [:type,:id,:item,:due_at,:action,:message,:task_assignment_collection,:is_completed,:created_by,:created_at]
36
- TASK_FIELDS_QUERY = TASK_FIELDS.join(',')
37
-
38
- COLLABORATION_FIELDS = [:type,:id,:created_by,:created_at,:modified_at,:expires_at,:status,:accessible_by,:role,:acknowledged_at,:item]
39
- COLLABORATION_FIELDS_QUERY = COLLABORATION_FIELDS.join(',')
40
-
41
- USER_FIELDS = [:type,:id,:name,:login,:created_at,:modified_at,:role,:language,:timezone,:space_amount,:space_used,
42
- :max_upload_size,:tracking_codes,:can_see_managed_users,:is_sync_enabled,:is_external_collab_restricted,
43
- :status,:job_title,:phone,:address,:avatar_uri,:is_exempt_from_device_limits,:is_exempt_from_login_verification,
44
- :enterprise,:my_tags]
45
- USER_FIELDS_QUERY = USER_FIELDS.join(',')
46
-
47
- GROUP_FIELDS = [:type, :id, :name, :created_at, :modified_at]
48
- GROUP_FIELDS_QUERY = GROUP_FIELDS.join(',')
49
-
50
- #Read this to see why the httpclient gem was chosen: http://bibwild.wordpress.com/2012/04/30/ruby-http-performance-shootout-redux/
51
- #All instances of Boxr::Client will use this one class instance of HTTPClient; that way persistent HTTPS connections work.
52
- #Plus, httpclient is thread-safe so we can use the same class instance with multiple instances of Boxr::Client
53
- BOX_CLIENT = HTTPClient.new
54
- BOX_CLIENT.send_timeout = 3600 #one hour; needed for lengthy uploads
55
- BOX_CLIENT.transparent_gzip_decompression = true
56
-
57
- def initialize(token, as_user_id: nil)
58
- @token = token
59
- @as_user_id = as_user_id
60
- end
61
-
62
- def debug_device=(device)
63
- if device
64
- BOX_CLIENT.debug_dev = device
65
- BOX_CLIENT.transparent_gzip_decompression = false
66
- else
67
- BOX_CLIENT.debug_dev = nil
68
- BOX_CLIENT.transparent_gzip_decompression = true
69
- end
70
- end
71
-
72
-
73
-
74
- private
75
-
76
- def get(uri, query: nil, success_codes: [200], process_response: true, if_match: nil, box_api_header: nil)
77
- headers = standard_headers()
78
- headers['If-Match'] = if_match unless if_match.nil?
79
- headers['BoxApi'] = box_api_header unless box_api_header.nil?
80
-
81
- res = BOX_CLIENT.get(uri, query: query, header: headers)
82
- check_response_status(res, success_codes)
83
-
84
- if process_response
85
- return processed_response res
86
- else
87
- return res.body, res
88
- end
89
- end
90
-
91
- def get_with_pagination(uri, query: {}, limit: DEFAULT_LIMIT)
92
- entries = []
93
- offset = 0
94
- headers = standard_headers()
95
-
96
- begin
97
- query[:limit] = limit
98
- query[:offset] = offset
99
- res = BOX_CLIENT.get(uri, query: query, header: headers)
100
-
101
- if (res.status==200)
102
- body_json = Oj.load(res.body)
103
- total_count = body_json["total_count"]
104
- offset = offset + limit
105
-
106
- entries << body_json["entries"]
107
- else
108
- raise BoxrException.new(status: res.status, body: res.body, header: res.header)
109
- end
110
- end until offset - total_count >= 0
111
-
112
- entries.flatten.map{|i| Hashie::Mash.new(i)}
113
- end
114
-
115
- def post(uri, body, query: nil, success_codes: [201], process_body: true, content_md5: nil, content_type: nil, if_match: nil)
116
- body = Oj.dump(body) if process_body
117
-
118
- headers = standard_headers()
119
- headers['If-Match'] = if_match unless if_match.nil?
120
- headers["Content-MD5"] = content_md5 unless content_md5.nil?
121
- headers["Content-Type"] = content_type unless content_type.nil?
122
-
123
- res = BOX_CLIENT.post(uri, body: body, query: query, header: headers)
124
- check_response_status(res, success_codes)
125
-
126
- processed_response res
127
- end
128
-
129
- def put(uri, body, query: nil, success_codes: [200], content_type: nil, if_match: nil)
130
- headers = standard_headers()
131
- headers['If-Match'] = if_match unless if_match.nil?
132
- headers["Content-Type"] = content_type unless content_type.nil?
133
-
134
- res = BOX_CLIENT.put(uri, body: Oj.dump(body), query: query, header: headers)
135
- check_response_status(res, success_codes)
136
-
137
- processed_response res
138
- end
139
-
140
- def delete(uri, query: nil, success_codes: [204], if_match: nil)
141
- headers = standard_headers()
142
- headers['If-Match'] = if_match unless if_match.nil?
143
-
144
- res = BOX_CLIENT.delete(uri, query: query, header: headers)
145
- check_response_status(res, success_codes)
146
-
147
- processed_response res
148
- end
149
-
150
- def options(uri, body, success_codes: [200])
151
- headers = standard_headers()
152
-
153
- res = BOX_CLIENT.options(uri, body: Oj.dump(body), header: headers)
154
- check_response_status(res, success_codes)
155
-
156
- processed_response res
157
- end
158
-
159
- def standard_headers()
160
- headers = {"Authorization" => "Bearer #{@token}"}
161
- headers['As-User'] = "#{@as_user_id}" unless @as_user_id.nil?
162
- headers
163
- end
164
-
165
- def check_response_status(res, success_codes)
166
- raise BoxrException.new(status: res.status, body: res.body, header: res.header) unless success_codes.include?(res.status)
167
- end
168
-
169
- def processed_response(res)
170
- body_json = Oj.load(res.body)
171
- return Hashie::Mash.new(body_json), res
172
- end
173
-
174
- def build_fields_query(fields, all_fields_query)
175
- if fields == :all
176
- {:fields => all_fields_query}
177
- elsif fields.is_a?(Array) && fields.length > 0
178
- {:fields => fields.join(',')}
179
- else
180
- {}
181
- end
182
- end
183
-
184
- def restore_trashed_item(uri, name, parent_id)
185
- attributes = {}
186
- attributes[:name] = name unless name.nil?
187
- attributes[:parent] = {id: parent_id} unless parent_id.nil?
188
-
189
- restored_item, response = post uri, attributes
190
- restored_item
191
- end
192
-
193
- def create_shared_link(uri, item_id, access, unshared_at, can_download, can_preview)
194
- if access.nil?
195
- attributes = {shared_link: {}}
196
- else
197
- attributes = {shared_link: {access: access}}
198
- attributes[:shared_link][:unshared_at] = unshared_at.to_datetime.rfc3339 if unshared_at
199
- attributes[:shared_link][:permissions] = {} unless can_download.nil? && can_preview.nil?
200
- attributes[:shared_link][:permissions][:can_download] = can_download unless can_download.nil?
201
- attributes[:shared_link][:permissions][:can_preview] = can_preview unless can_preview.nil?
202
- end
203
-
204
- updated_item, response = put uri, attributes
205
- updated_item
206
- end
207
-
208
- def disable_shared_link(uri, item_id)
209
- attributes = {shared_link: nil}
210
-
211
- updated_item, response = put uri, attributes
212
- updated_item
213
- end
214
-
215
- end
2
+
3
+ class Client
4
+
5
+ attr_reader :access_token, :refresh_token, :box_client_id, :box_client_secret, :identifier, :as_user_id
6
+
7
+ API_URI = "https://api.box.com/2.0"
8
+ UPLOAD_URI = "https://upload.box.com/api/2.0"
9
+ FILES_URI = "#{API_URI}/files"
10
+ FILES_UPLOAD_URI = "#{UPLOAD_URI}/files/content"
11
+ FOLDERS_URI = "#{API_URI}/folders"
12
+ USERS_URI = "#{API_URI}/users"
13
+ GROUPS_URI = "#{API_URI}/groups"
14
+ GROUP_MEMBERSHIPS_URI = "#{API_URI}/group_memberships"
15
+ COLLABORATIONS_URI = "#{API_URI}/collaborations"
16
+ COMMENTS_URI = "#{API_URI}/comments"
17
+ SEARCH_URI = "#{API_URI}/search"
18
+ TASKS_URI = "#{API_URI}/tasks"
19
+ TASK_ASSIGNMENTS_URI = "#{API_URI}/task_assignments"
20
+ SHARED_ITEMS_URI = "#{API_URI}/shared_items"
21
+ METADATA_URI = "#{API_URI}/files"
22
+ EVENTS_URI = "#{API_URI}/events"
23
+
24
+ DEFAULT_LIMIT = 100
25
+ FOLDER_ITEMS_LIMIT = 1000
26
+
27
+ FOLDER_AND_FILE_FIELDS = [:type,:id,:sequence_id,:etag,:name,:created_at,:modified_at,:description,
28
+ :size,:path_collection,:created_by,:modified_by,:trashed_at,:purged_at,
29
+ :content_created_at,:content_modified_at,:owned_by,:shared_link,:folder_upload_email,
30
+ :parent,:item_status,:item_collection,:sync_state,:has_collaborations,:permissions,:tags,
31
+ :sha1,:shared_link,:version_number,:comment_count,:lock,:extension,:is_package,:can_non_owners_invite]
32
+ FOLDER_AND_FILE_FIELDS_QUERY = FOLDER_AND_FILE_FIELDS.join(',')
33
+
34
+ COMMENT_FIELDS = [:type,:id,:is_reply_comment,:message,:tagged_message,:created_by,:created_at,:item,:modified_at]
35
+ COMMENT_FIELDS_QUERY = COMMENT_FIELDS.join(',')
36
+
37
+ TASK_FIELDS = [:type,:id,:item,:due_at,:action,:message,:task_assignment_collection,:is_completed,:created_by,:created_at]
38
+ TASK_FIELDS_QUERY = TASK_FIELDS.join(',')
39
+
40
+ COLLABORATION_FIELDS = [:type,:id,:created_by,:created_at,:modified_at,:expires_at,:status,:accessible_by,:role,:acknowledged_at,:item]
41
+ COLLABORATION_FIELDS_QUERY = COLLABORATION_FIELDS.join(',')
42
+
43
+ USER_FIELDS = [:type,:id,:name,:login,:created_at,:modified_at,:role,:language,:timezone,:space_amount,:space_used,
44
+ :max_upload_size,:tracking_codes,:can_see_managed_users,:is_sync_enabled,:is_external_collab_restricted,
45
+ :status,:job_title,:phone,:address,:avatar_uri,:is_exempt_from_device_limits,:is_exempt_from_login_verification,
46
+ :enterprise,:my_tags]
47
+ USER_FIELDS_QUERY = USER_FIELDS.join(',')
48
+
49
+ GROUP_FIELDS = [:type, :id, :name, :created_at, :modified_at]
50
+ GROUP_FIELDS_QUERY = GROUP_FIELDS.join(',')
51
+
52
+ #Read this to see why the httpclient gem was chosen: http://bibwild.wordpress.com/2012/04/30/ruby-http-performance-shootout-redux/
53
+ #All instances of Boxr::Client will use this one class instance of HTTPClient; that way persistent HTTPS connections work.
54
+ #Plus, httpclient is thread-safe so we can use the same class instance with multiple instances of Boxr::Client
55
+ BOX_CLIENT = HTTPClient.new
56
+ BOX_CLIENT.send_timeout = 3600 #one hour; needed for lengthy uploads
57
+ BOX_CLIENT.transparent_gzip_decompression = true
58
+
59
+ def self.turn_on_debugging(device=STDOUT)
60
+ BOX_CLIENT.debug_dev = device
61
+ BOX_CLIENT.transparent_gzip_decompression = false
62
+ end
63
+
64
+ def self.turn_off_debugging
65
+ BOX_CLIENT.debug_dev = nil
66
+ BOX_CLIENT.transparent_gzip_decompression = true
67
+ end
68
+
69
+ def initialize(access_token, refresh_token: nil, box_client_id: ENV['BOX_CLIENT_ID'], box_client_secret: ENV['BOX_CLIENT_SECRET'],
70
+ identifier: nil, as_user_id: nil, &token_refresh_listener)
71
+ @access_token = access_token
72
+ @refresh_token = refresh_token
73
+ @box_client_id = box_client_id
74
+ @box_client_secret = box_client_secret
75
+ @identifier = identifier
76
+ @as_user_id = as_user_id
77
+ @token_refresh_listener = token_refresh_listener
78
+ end
79
+
80
+
81
+ private
82
+
83
+ def get(uri, query: nil, success_codes: [200], process_response: true, if_match: nil, box_api_header: nil)
84
+ res = with_auto_token_refresh do
85
+ headers = standard_headers()
86
+ headers['If-Match'] = if_match unless if_match.nil?
87
+ headers['BoxApi'] = box_api_header unless box_api_header.nil?
88
+
89
+ BOX_CLIENT.get(uri, query: query, header: headers)
90
+ end
91
+
92
+ check_response_status(res, success_codes)
93
+
94
+ if process_response
95
+ return processed_response res
96
+ else
97
+ return res.body, res
98
+ end
99
+ end
100
+
101
+ def get_with_pagination(uri, query: {}, limit: DEFAULT_LIMIT)
102
+ entries = []
103
+ offset = 0
104
+
105
+ begin
106
+ query[:limit] = limit
107
+ query[:offset] = offset
108
+ res = with_auto_token_refresh do
109
+ headers = standard_headers()
110
+ BOX_CLIENT.get(uri, query: query, header: headers)
111
+ end
112
+
113
+ if (res.status==200)
114
+ body_json = Oj.load(res.body)
115
+ total_count = body_json["total_count"]
116
+ offset = offset + limit
117
+
118
+ entries << body_json["entries"]
119
+ else
120
+ raise BoxrException.new(status: res.status, body: res.body, header: res.header)
121
+ end
122
+ end until offset - total_count >= 0
123
+
124
+ entries.flatten.map{|i| Hashie::Mash.new(i)}
125
+ end
126
+
127
+ def post(uri, body, query: nil, success_codes: [201], process_body: true, content_md5: nil, content_type: nil, if_match: nil)
128
+ body = Oj.dump(body) if process_body
129
+
130
+ res = with_auto_token_refresh do
131
+ headers = standard_headers()
132
+ headers['If-Match'] = if_match unless if_match.nil?
133
+ headers["Content-MD5"] = content_md5 unless content_md5.nil?
134
+ headers["Content-Type"] = content_type unless content_type.nil?
135
+
136
+ BOX_CLIENT.post(uri, body: body, query: query, header: headers)
137
+ end
138
+
139
+ check_response_status(res, success_codes)
140
+
141
+ processed_response res
142
+ end
143
+
144
+ def put(uri, body, query: nil, success_codes: [200], content_type: nil, if_match: nil)
145
+ res = with_auto_token_refresh do
146
+ headers = standard_headers()
147
+ headers['If-Match'] = if_match unless if_match.nil?
148
+ headers["Content-Type"] = content_type unless content_type.nil?
149
+
150
+ BOX_CLIENT.put(uri, body: Oj.dump(body), query: query, header: headers)
151
+ end
152
+
153
+ check_response_status(res, success_codes)
154
+
155
+ processed_response res
156
+ end
157
+
158
+ def delete(uri, query: nil, success_codes: [204], if_match: nil)
159
+ res = with_auto_token_refresh do
160
+ headers = standard_headers()
161
+ headers['If-Match'] = if_match unless if_match.nil?
162
+
163
+ BOX_CLIENT.delete(uri, query: query, header: headers)
164
+ end
165
+
166
+ check_response_status(res, success_codes)
167
+
168
+ processed_response res
169
+ end
170
+
171
+ def options(uri, body, success_codes: [200])
172
+ res = with_auto_token_refresh do
173
+ headers = standard_headers()
174
+ BOX_CLIENT.options(uri, body: Oj.dump(body), header: headers)
175
+ end
176
+
177
+ check_response_status(res, success_codes)
178
+
179
+ processed_response res
180
+ end
181
+
182
+ def standard_headers()
183
+ headers = {"Authorization" => "Bearer #{@access_token}"}
184
+ headers['As-User'] = "#{@as_user_id}" unless @as_user_id.nil?
185
+ headers
186
+ end
187
+
188
+ def with_auto_token_refresh
189
+ return yield unless @refresh_token
190
+
191
+ res = yield
192
+ if res.status == 401
193
+ auth_header = res.header['WWW-Authenticate'][0]
194
+ if auth_header && auth_header.include?('invalid_token')
195
+ new_tokens = Boxr::refresh_tokens(@refresh_token, box_client_id: box_client_id, box_client_secret: box_client_secret)
196
+ @access_token = new_tokens.access_token
197
+ @refresh_token = new_tokens.refresh_token
198
+ @token_refresh_listener.call(@access_token, @refresh_token, @identifier) if @token_refresh_listener
199
+ res = yield
200
+ end
201
+ end
202
+
203
+ res
204
+ end
205
+
206
+ def check_response_status(res, success_codes)
207
+ raise BoxrException.new(status: res.status, body: res.body, header: res.header) unless success_codes.include?(res.status)
208
+ end
209
+
210
+ def processed_response(res)
211
+ body_json = Oj.load(res.body)
212
+ return Hashie::Mash.new(body_json), res
213
+ end
214
+
215
+ def build_fields_query(fields, all_fields_query)
216
+ if fields == :all
217
+ {:fields => all_fields_query}
218
+ elsif fields.is_a?(Array) && fields.length > 0
219
+ {:fields => fields.join(',')}
220
+ else
221
+ {}
222
+ end
223
+ end
224
+
225
+ def restore_trashed_item(uri, name, parent_id)
226
+ attributes = {}
227
+ attributes[:name] = name unless name.nil?
228
+ attributes[:parent] = {id: parent_id} unless parent_id.nil?
229
+
230
+ restored_item, response = post uri, attributes
231
+ restored_item
232
+ end
233
+
234
+ def create_shared_link(uri, item_id, access, unshared_at, can_download, can_preview)
235
+ if access.nil?
236
+ attributes = {shared_link: {}}
237
+ else
238
+ attributes = {shared_link: {access: access}}
239
+ attributes[:shared_link][:unshared_at] = unshared_at.to_datetime.rfc3339 unless unshared_at.nil?
240
+ attributes[:shared_link][:permissions] = {} unless can_download.nil? && can_preview.nil?
241
+ attributes[:shared_link][:permissions][:can_download] = can_download unless can_download.nil?
242
+ attributes[:shared_link][:permissions][:can_preview] = can_preview unless can_preview.nil?
243
+ end
244
+
245
+ updated_item, response = put uri, attributes
246
+ updated_item
247
+ end
248
+
249
+ def disable_shared_link(uri, item_id)
250
+ attributes = {shared_link: nil}
251
+
252
+ updated_item, response = put uri, attributes
253
+ updated_item
254
+ end
255
+
256
+ end
216
257
 
217
258
  end