Module: Boxr

Defined in:
lib/boxr.rb,
lib/boxr/auth.rb,
lib/boxr/files.rb,
lib/boxr/tasks.rb,
lib/boxr/users.rb,
lib/boxr/client.rb,
lib/boxr/errors.rb,
lib/boxr/events.rb,
lib/boxr/groups.rb,
lib/boxr/search.rb,
lib/boxr/folders.rb,
lib/boxr/version.rb,
lib/boxr/comments.rb,
lib/boxr/metadata.rb,
lib/boxr/webhooks.rb,
lib/boxr/web_links.rb,
lib/boxr/collections.rb,
lib/boxr/shared_items.rb,
lib/boxr/watermarking.rb,
lib/boxr/zip_downloads.rb,
lib/boxr/collaborations.rb,
lib/boxr/chunked_uploads.rb,
lib/boxr/webhook_validator.rb

Defined Under Namespace

Classes: BoxrError, Client, WebhookValidator

Constant Summary collapse

ROOT =

The root folder in Box is always identified by 0

0
BOX_CLIENT =

HTTPClient is high-performance, thread-safe, and supports persistent HTTPS connections bibwild.wordpress.com/2012/04/30/ruby-http-performance-shootout-redux/

HTTPClient.new
JWT_GRANT_TYPE =
'urn:ietf:params:oauth:grant-type:jwt-bearer'
TOKEN_EXCHANGE_TOKEN_TYPE =
'urn:ietf:params:oauth:token-type:access_token'
TOKEN_EXCHANGE_GRANT_TYPE =
'urn:ietf:params:oauth:grant-type:token-exchange'
VERSION =
'1.23.1'

Class Method Summary collapse

Class Method Details

.auth_post(uri, body) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/boxr/auth.rb', line 102

def self.auth_post(uri, body)
  uri = Addressable::URI.encode(uri)

  res = BOX_CLIENT.post(uri, body: body)

  unless res.status == 200
    raise BoxrError.new(status: res.status, body: res.body, header: res.header)
  end

  body_json = JSON.parse(res.body)
  BoxrMash.new(body_json)
end

.exchange_token(subject_token, scope, resource_id: nil, resource_type: :file) ⇒ Object

Exchange an existing token for a lesser-scoped token



69
70
71
72
73
74
75
76
77
78
# File 'lib/boxr/auth.rb', line 69

def self.exchange_token(subject_token, scope, resource_id: nil, resource_type: :file)
  uri = Boxr::Client::AUTH_URI
  resouce_uri = resource_type == :file ? Boxr::Client::FILES_URI : Boxr::Client::FOLDERS_URI
  resource_url = "#{resouce_uri}/#{resource_id}"

  body = "subject_token=#{subject_token}&subject_token_type=#{TOKEN_EXCHANGE_TOKEN_TYPE}&scope=#{scope}&grant_type=#{TOKEN_EXCHANGE_GRANT_TYPE}"
  body += "&resource=#{resource_url}" unless resource_id.nil?

  auth_post(uri, body)
end

.get_enterprise_token(private_key: , private_key_password: , public_key_id: , enterprise_id: , client_id: , client_secret: ) ⇒ Object



34
35
36
37
38
39
40
41
42
# File 'lib/boxr/auth.rb', line 34

def self.get_enterprise_token(private_key: ENV['JWT_PRIVATE_KEY'], private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],
                              public_key_id: ENV['JWT_PUBLIC_KEY_ID'], enterprise_id: ENV['BOX_ENTERPRISE_ID'],
                              client_id: ENV['BOX_CLIENT_ID'], client_secret: ENV['BOX_CLIENT_SECRET'])
  unlocked_private_key = unlock_key(private_key, private_key_password)
  assertion = jwt_assertion(unlocked_private_key, client_id, enterprise_id, 'enterprise',
                            public_key_id)
  get_token(grant_type: JWT_GRANT_TYPE, assertion: assertion, client_id: client_id,
            client_secret: client_secret)
end

.get_tokens(code = nil, grant_type: 'authorization_code', assertion: nil, scope: nil, username: nil, client_id: , client_secret: , box_subject_type: nil, box_subject_id: nil) ⇒ Object Also known as: get_token



20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/boxr/auth.rb', line 20

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'], box_subject_type: nil, box_subject_id: nil)
  uri = Boxr::Client::AUTH_URI
  body = "grant_type=#{grant_type}&client_id=#{client_id}&client_secret=#{client_secret}"
  body += "&code=#{code}" unless code.nil?
  body += "&scope=#{scope}" unless scope.nil?
  body += "&username=#{username}" unless username.nil?
  body += "&assertion=#{assertion}" unless assertion.nil?
  body += "&box_subject_type=#{box_subject_type}" unless box_subject_type.nil?
  body += "&box_subject_id=#{box_subject_id}" unless box_subject_id.nil?

  auth_post(uri, body)
end

.get_user_token(user_id, private_key: , private_key_password: , public_key_id: , client_id: , client_secret: ) ⇒ Object



44
45
46
47
48
49
50
# File 'lib/boxr/auth.rb', line 44

def self.get_user_token(user_id, private_key: ENV['JWT_PRIVATE_KEY'], private_key_password: ENV['JWT_PRIVATE_KEY_PASSWORD'],
                        public_key_id: ENV['JWT_PUBLIC_KEY_ID'], client_id: ENV['BOX_CLIENT_ID'], client_secret: ENV['BOX_CLIENT_SECRET'])
  unlocked_private_key = unlock_key(private_key, private_key_password)
  assertion = jwt_assertion(unlocked_private_key, client_id, user_id, 'user', public_key_id)
  get_token(grant_type: JWT_GRANT_TYPE, assertion: assertion, client_id: client_id,
            client_secret: client_secret)
end

.jwt_assertion(private_key, iss, sub, box_sub_type, public_key_id) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/boxr/auth.rb', line 86

def self.jwt_assertion(private_key, iss, sub, box_sub_type, public_key_id)
  payload = {
    iss: iss,
    sub: sub,
    box_sub_type: box_sub_type,
    aud: Boxr::Client::AUTH_URI,
    jti: SecureRandom.hex(64),
    exp: (Time.now.utc + 10).to_i
  }

  additional_headers = {}
  additional_headers['kid'] = public_key_id unless public_key_id.nil?

  JWT.encode(payload, private_key, 'RS256', additional_headers)
end

.oauth_url(state, host: 'app.box.com', response_type: 'code', scope: nil, folder_id: nil, client_id: ENV['BOX_CLIENT_ID']) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
# File 'lib/boxr/auth.rb', line 8

def self.oauth_url(state, host: 'app.box.com', response_type: 'code', scope: nil, folder_id: nil,
                   client_id: ENV['BOX_CLIENT_ID'])
  template = Addressable::Template.new('https://{host}/api/oauth2/authorize{?query*}')

  query = { 'response_type' => response_type.to_s, 'state' => state.to_s,
            'client_id' => client_id.to_s }
  query['scope'] = scope.to_s unless scope.nil?
  query['folder_id'] = folder_id.to_s unless folder_id.nil?

  template.expand({ 'host' => host.to_s, 'query' => query })
end

.refresh_tokens(refresh_token, client_id: , client_secret: ) ⇒ Object Also known as: refresh_token



52
53
54
55
56
57
58
# File 'lib/boxr/auth.rb', line 52

def self.refresh_tokens(refresh_token, client_id: ENV['BOX_CLIENT_ID'],
                        client_secret: ENV['BOX_CLIENT_SECRET'])
  uri = Boxr::Client::AUTH_URI
  body = "grant_type=refresh_token&refresh_token=#{refresh_token}&client_id=#{client_id}&client_secret=#{client_secret}"

  auth_post(uri, body)
end

.revoke_tokens(token, client_id: , client_secret: ) ⇒ Object Also known as: revoke_token



60
61
62
63
64
65
66
# File 'lib/boxr/auth.rb', line 60

def self.revoke_tokens(token, client_id: ENV['BOX_CLIENT_ID'],
                       client_secret: ENV['BOX_CLIENT_SECRET'])
  uri = Boxr::Client::REVOKE_AUTH_URI
  body = "client_id=#{client_id}&client_secret=#{client_secret}&token=#{token}"

  auth_post(uri, body)
end

.turn_off_debuggingObject



86
87
88
89
90
# File 'lib/boxr.rb', line 86

def self.turn_off_debugging
  BOX_CLIENT.debug_dev = nil
  BOX_CLIENT.transparent_gzip_decompression = true
  nil
end

.turn_on_debugging(device = $stdout) ⇒ Object

BOX_CLIENT.ssl_config.add_trust_ca(“/Users/cburnette/code/ssh-keys/dev_root_ca.pem”)



80
81
82
83
84
# File 'lib/boxr.rb', line 80

def self.turn_on_debugging(device = $stdout)
  BOX_CLIENT.debug_dev = device
  BOX_CLIENT.transparent_gzip_decompression = false
  nil
end

.unlock_key(private_key, private_key_password) ⇒ Object



115
116
117
118
119
120
121
# File 'lib/boxr/auth.rb', line 115

def self.unlock_key(private_key, private_key_password)
  if private_key.is_a?(OpenSSL::PKey::RSA)
    private_key
  else
    OpenSSL::PKey::RSA.new(private_key, private_key_password)
  end
end