boxr 1.8.0 → 1.9.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 +4 -4
- data/.env.example +3 -3
- data/.gitignore +1 -0
- data/README.md +3 -0
- data/lib/boxr/auth.rb +22 -9
- data/lib/boxr/client.rb +2 -0
- data/lib/boxr/version.rb +1 -1
- data/spec/boxr/auth_spec.rb +31 -0
- data/spec/boxr/collaborations_spec.rb +1 -1
- data/spec/boxr_spec.rb +4 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2229eb1062b34eabf5e7040caf0a2c497caa7d2ef13c75f896eb76e1e7c25fea
|
4
|
+
data.tar.gz: 4404394473173cfa99b4f5b22af110fa2dbd1f9018262fa3b4c48c49f51ba99a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 958241267042bcdcbd94247873beefe73afbd43da4860047411c5891fcc25cd56555b719b2f760d9e949c14e6a88c4a90e7658b4c12cc11b4a592c367f02ddf0
|
7
|
+
data.tar.gz: 8d6c582d64c0be4ca4da7cc87f629b2735d90b4640eb2ee154b9cf32597e2f3fa9f65c1fe2c544c075d671d1d0a8d89ac7eabc42cc86fc69ec7d68e9487d524a
|
data/.env.example
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#1. go to https://developers.box.com,
|
1
|
+
#1. go to https://developers.box.com,
|
2
2
|
#2. find or create your Box Content API app for testing
|
3
3
|
#3. click 'Edit Application'
|
4
4
|
#4. check the boxes for 'Read and write all files and folders' and 'Manage an enterprise'
|
@@ -11,5 +11,5 @@ BOX_DEVELOPER_TOKEN={a valid developer token for your Box app}
|
|
11
11
|
BOX_CLIENT_ID={client id of your Box app}
|
12
12
|
BOX_CLIENT_SECRET={client secret of your Box app}
|
13
13
|
BOX_ENTERPRISE_ID={box enterprise id}
|
14
|
-
|
15
|
-
|
14
|
+
JWT_PRIVATE_KEY_PATH={path to your JWT private key}
|
15
|
+
JWT_PRIVATE_KEY_PASSWORD={JWT private key password}
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
# Boxr
|
2
|
+
|
3
|
+
[](https://badge.fury.io/rb/boxr)
|
4
|
+
|
2
5
|
Boxr is a Ruby client library for the Box V2 Content API. Box employees affectionately refer to one another as Boxers, hence the name of this gem.
|
3
6
|
|
4
7
|
The purpose of this gem is to provide a clear, efficient, and intentional method of interacting with the Box Content API. As with any SDK that wraps a REST API, it is important to fully understand the Box Content API at the REST endpoint level. You are strongly encouraged to read through the Box documentation located [here](https://box-content.readme.io/).
|
data/lib/boxr/auth.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Boxr
|
2
2
|
|
3
3
|
JWT_GRANT_TYPE="urn:ietf:params:oauth:grant-type:jwt-bearer"
|
4
|
+
TOKEN_EXCHANGE_TOKEN_TYPE="urn:ietf:params:oauth:token-type:access_token"
|
5
|
+
TOKEN_EXCHANGE_GRANT_TYPE="urn:ietf:params:oauth:grant-type:token-exchange"
|
4
6
|
|
5
7
|
def self.oauth_url(state, host: "app.box.com", response_type: "code", scope: nil, folder_id: nil, client_id: ENV['BOX_CLIENT_ID'])
|
6
8
|
template = Addressable::Template.new("https://{host}/api/oauth2/authorize{?query*}")
|
@@ -8,13 +10,13 @@ module Boxr
|
|
8
10
|
query = {"response_type" => "#{response_type}", "state" => "#{state}", "client_id" => "#{client_id}"}
|
9
11
|
query["scope"] = "#{scope}" unless scope.nil?
|
10
12
|
query["folder_id"] = "#{folder_id}" unless folder_id.nil?
|
11
|
-
|
13
|
+
|
12
14
|
uri = template.expand({"host" => "#{host}", "query" => query})
|
13
15
|
uri
|
14
16
|
end
|
15
17
|
|
16
18
|
def self.get_tokens(code=nil, grant_type: "authorization_code", assertion: nil, scope: nil, username: nil, client_id: ENV['BOX_CLIENT_ID'], client_secret: ENV['BOX_CLIENT_SECRET'])
|
17
|
-
uri =
|
19
|
+
uri = Boxr::Client::AUTH_URI
|
18
20
|
body = "grant_type=#{grant_type}&client_id=#{client_id}&client_secret=#{client_secret}"
|
19
21
|
body = body + "&code=#{code}" unless code.nil?
|
20
22
|
body = body + "&scope=#{scope}" unless scope.nil?
|
@@ -25,7 +27,7 @@ module Boxr
|
|
25
27
|
end
|
26
28
|
|
27
29
|
def self.get_enterprise_token(private_key: ENV['JWT_PRIVATE_KEY'], private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],
|
28
|
-
public_key_id: ENV['JWT_PUBLIC_KEY_ID'], enterprise_id: ENV['BOX_ENTERPRISE_ID'],
|
30
|
+
public_key_id: ENV['JWT_PUBLIC_KEY_ID'], enterprise_id: ENV['BOX_ENTERPRISE_ID'],
|
29
31
|
client_id: ENV['BOX_CLIENT_ID'], client_secret: ENV['BOX_CLIENT_SECRET'])
|
30
32
|
unlocked_private_key = unlock_key(private_key, private_key_password)
|
31
33
|
assertion = jwt_assertion(unlocked_private_key, client_id, enterprise_id, "enterprise", public_key_id)
|
@@ -40,19 +42,31 @@ module Boxr
|
|
40
42
|
end
|
41
43
|
|
42
44
|
def self.refresh_tokens(refresh_token, client_id: ENV['BOX_CLIENT_ID'], client_secret: ENV['BOX_CLIENT_SECRET'])
|
43
|
-
uri =
|
45
|
+
uri = Boxr::Client::AUTH_URI
|
44
46
|
body = "grant_type=refresh_token&refresh_token=#{refresh_token}&client_id=#{client_id}&client_secret=#{client_secret}"
|
45
47
|
|
46
48
|
auth_post(uri, body)
|
47
49
|
end
|
48
50
|
|
49
51
|
def self.revoke_tokens(token, client_id: ENV['BOX_CLIENT_ID'], client_secret: ENV['BOX_CLIENT_SECRET'])
|
50
|
-
uri =
|
52
|
+
uri = Boxr::Client::REVOKE_AUTH_URI
|
51
53
|
body = "client_id=#{client_id}&client_secret=#{client_secret}&token=#{token}"
|
52
54
|
|
53
55
|
auth_post(uri, body)
|
54
56
|
end
|
55
57
|
|
58
|
+
# Exchange an existing token for a lesser-scoped token
|
59
|
+
def self.exchange_token(subject_token, scope, resource_id: nil, resource_type: :file)
|
60
|
+
uri = Boxr::Client::AUTH_URI
|
61
|
+
resouce_uri = resource_type == :file ? Boxr::Client::FILES_URI : Boxr::Client::FOLDERS_URI
|
62
|
+
resource_url = "#{resouce_uri}/#{resource_id}"
|
63
|
+
|
64
|
+
body = "subject_token=#{subject_token}&subject_token_type=#{TOKEN_EXCHANGE_TOKEN_TYPE}&scope=#{scope}&grant_type=#{TOKEN_EXCHANGE_GRANT_TYPE}"
|
65
|
+
body = body + "&resource=#{resource_url}" unless resource_id.nil?
|
66
|
+
|
67
|
+
auth_post(uri, body)
|
68
|
+
end
|
69
|
+
|
56
70
|
class << self
|
57
71
|
alias :get_token :get_tokens
|
58
72
|
alias :refresh_token :refresh_tokens
|
@@ -67,14 +81,14 @@ module Boxr
|
|
67
81
|
iss: iss,
|
68
82
|
sub: sub,
|
69
83
|
box_sub_type: box_sub_type,
|
70
|
-
aud:
|
84
|
+
aud: Boxr::Client::AUTH_URI,
|
71
85
|
jti: SecureRandom.hex(64),
|
72
86
|
exp: (Time.now.utc + 10).to_i
|
73
87
|
}
|
74
88
|
|
75
89
|
additional_headers = {}
|
76
90
|
additional_headers['kid'] = public_key_id unless public_key_id.nil?
|
77
|
-
|
91
|
+
|
78
92
|
JWT.encode(payload, private_key, "RS256", additional_headers)
|
79
93
|
end
|
80
94
|
|
@@ -98,5 +112,4 @@ module Boxr
|
|
98
112
|
OpenSSL::PKey::RSA.new(private_key, private_key_password)
|
99
113
|
end
|
100
114
|
end
|
101
|
-
|
102
|
-
end
|
115
|
+
end
|
data/lib/boxr/client.rb
CHANGED
@@ -8,6 +8,8 @@ module Boxr
|
|
8
8
|
#UPLOAD_URI = "https://upload.wcheng.inside-box.net/api/2.0"
|
9
9
|
|
10
10
|
API_URI = "https://api.box.com/2.0"
|
11
|
+
AUTH_URI = "https://api.box.com/oauth2/token"
|
12
|
+
REVOKE_AUTH_URI = "https://api.box.com/oauth2/revoke"
|
11
13
|
UPLOAD_URI = "https://upload.box.com/api/2.0"
|
12
14
|
FILES_URI = "#{API_URI}/files"
|
13
15
|
FILES_UPLOAD_URI = "#{UPLOAD_URI}/files/content"
|
data/lib/boxr/version.rb
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
#rake spec SPEC_OPTS="-e \"invokes auth operations"\"
|
4
|
+
describe 'auth operations' do
|
5
|
+
it "invokes auth operations" do
|
6
|
+
private_key = OpenSSL::PKey::RSA.new(File.read(ENV['JWT_PRIVATE_KEY_PATH']), ENV['JWT_PRIVATE_KEY_PASSWORD'])
|
7
|
+
|
8
|
+
puts "get enterprise token"
|
9
|
+
enterprise_token = Boxr::get_enterprise_token(private_key: private_key)
|
10
|
+
expect(enterprise_token).to include('access_token', 'expires_in')
|
11
|
+
|
12
|
+
puts "downgrade token"
|
13
|
+
child_token = Boxr::exchange_token(enterprise_token['access_token'], 'root_readonly')
|
14
|
+
expect(child_token).to include('access_token','expires_in')
|
15
|
+
|
16
|
+
# Currently cannot test due to user requiring
|
17
|
+
puts "get user token"
|
18
|
+
second_test_user = BOX_CLIENT.create_user("Second Test User", login: "second_test_user@#{('a'..'z').to_a.shuffle[0,10].join}.com", role: 'user', is_platform_access_only: true)
|
19
|
+
user_token = Boxr::get_user_token(second_test_user.id, private_key: private_key)
|
20
|
+
expect(user_token).to include('access_token','expires_in')
|
21
|
+
|
22
|
+
puts "revoke user token"
|
23
|
+
user_client = Boxr::Client.new(user_token['access_token'])
|
24
|
+
expect(user_client.root_folder_items).to eq []
|
25
|
+
Boxr::revoke_token(user_token['access_token'])
|
26
|
+
expect{user_client.root_folder_items}.to raise_error{Boxr::BoxrError}
|
27
|
+
|
28
|
+
puts "cleanup data"
|
29
|
+
BOX_CLIENT.delete_user(second_test_user, force: true)
|
30
|
+
end
|
31
|
+
end
|
@@ -32,6 +32,6 @@ describe 'collaborations operations' do
|
|
32
32
|
expect(pending_collaborations).to eq([])
|
33
33
|
|
34
34
|
puts "add invalid collaboration"
|
35
|
-
expect { BOX_CLIENT.add_collaboration(@test_folder, {id: @test_user.id, type: :user}, :invalid_role)}.to raise_error
|
35
|
+
expect { BOX_CLIENT.add_collaboration(@test_folder, {id: @test_user.id, type: :user}, :invalid_role)}.to raise_error{Boxr::BoxrError}
|
36
36
|
end
|
37
37
|
end
|
data/spec/boxr_spec.rb
CHANGED
@@ -10,7 +10,11 @@ describe Boxr::Client do
|
|
10
10
|
|
11
11
|
#REQUIRED BOX SETTINGS
|
12
12
|
# 1. The developer token used must have admin or co-admin priviledges
|
13
|
+
# 1.5 In the admin settings, advanced features must be enabled (perform as user and create user access tokens)
|
13
14
|
# 2. Enterprise settings must allow Admin and Co-admins to permanently delete content in Trash
|
15
|
+
# 3. In Box Admin settings, you must authorize the app.
|
16
|
+
# - Admin Console > Enterprise Settings > Apps > Custom Applications > Authorize New App. Insert you client ID (API key)
|
17
|
+
# - You may need to re-authorize the app if you're running into issues with user tokens
|
14
18
|
|
15
19
|
#follow the directions in .env.example to set up your BOX_DEVELOPER_TOKEN
|
16
20
|
#keep in mind it is only valid for 60 minutes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: boxr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chad Burnette
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -209,6 +209,7 @@ files:
|
|
209
209
|
- lib/boxr/version.rb
|
210
210
|
- lib/boxr/watermarking.rb
|
211
211
|
- lib/boxr/web_links.rb
|
212
|
+
- spec/boxr/auth_spec.rb
|
212
213
|
- spec/boxr/collaborations_spec.rb
|
213
214
|
- spec/boxr/comments_spec.rb
|
214
215
|
- spec/boxr/files_spec.rb
|
@@ -247,6 +248,7 @@ signing_key:
|
|
247
248
|
specification_version: 4
|
248
249
|
summary: A Ruby client library for the Box V2 Content API.
|
249
250
|
test_files:
|
251
|
+
- spec/boxr/auth_spec.rb
|
250
252
|
- spec/boxr/collaborations_spec.rb
|
251
253
|
- spec/boxr/comments_spec.rb
|
252
254
|
- spec/boxr/files_spec.rb
|