podio 0.7.0 → 0.8.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.
Files changed (54) hide show
  1. data/Rakefile +0 -16
  2. data/lib/podio.rb +6 -3
  3. data/lib/podio/active_podio/base.rb +53 -21
  4. data/lib/podio/active_podio/updatable.rb +9 -14
  5. data/lib/podio/client.rb +46 -17
  6. data/lib/podio/error.rb +9 -0
  7. data/lib/podio/middleware/error_response.rb +5 -1
  8. data/lib/podio/middleware/json_request.rb +27 -5
  9. data/lib/podio/models/account_provider.rb +16 -0
  10. data/lib/podio/models/app_store_category.rb +25 -0
  11. data/lib/podio/models/app_store_share.rb +90 -11
  12. data/lib/podio/models/application.rb +52 -12
  13. data/lib/podio/models/application_field.rb +4 -4
  14. data/lib/podio/models/batch.rb +31 -0
  15. data/lib/podio/models/calendar_event.rb +64 -10
  16. data/lib/podio/models/category.rb +11 -9
  17. data/lib/podio/models/contact.rb +3 -1
  18. data/lib/podio/models/contract.rb +3 -0
  19. data/lib/podio/models/email_subscription_setting.rb +26 -3
  20. data/lib/podio/models/file_attachment.rb +3 -2
  21. data/lib/podio/models/form.rb +2 -2
  22. data/lib/podio/models/importer.rb +18 -9
  23. data/lib/podio/models/item.rb +87 -22
  24. data/lib/podio/models/item_field.rb +8 -3
  25. data/lib/podio/models/linked_account.rb +11 -3
  26. data/lib/podio/models/linked_account_data.rb +6 -0
  27. data/lib/podio/models/news.rb +1 -0
  28. data/lib/podio/models/organization.rb +4 -0
  29. data/lib/podio/models/organization_member.rb +17 -4
  30. data/lib/podio/models/organization_profile.rb +5 -1
  31. data/lib/podio/models/profile.rb +19 -10
  32. data/lib/podio/models/reference.rb +33 -0
  33. data/lib/podio/models/search.rb +4 -7
  34. data/lib/podio/models/space.rb +21 -12
  35. data/lib/podio/models/space_invitation.rb +7 -7
  36. data/lib/podio/models/space_member.rb +28 -3
  37. data/lib/podio/models/task.rb +38 -14
  38. data/lib/podio/models/user.rb +27 -5
  39. data/lib/podio/models/user_status.rb +5 -0
  40. data/lib/podio/models/view.rb +51 -0
  41. data/lib/podio/models/widget.rb +1 -1
  42. data/lib/podio/version.rb +1 -1
  43. data/test/client_test.rb +13 -3
  44. data/test/fixtures/fixtures.yaml +7 -7
  45. data/test/test_helper.rb +1 -24
  46. metadata +16 -23
  47. data/lib/podio/middleware/response_recorder.rb +0 -14
  48. data/lib/podio/models/meeting.rb +0 -151
  49. data/lib/podio/models/meeting_participiant.rb +0 -11
  50. data/test/fixtures/client/18a224aaf83ac57a7b8159cecdbb1263.rack +0 -1
  51. data/test/fixtures/client/a87c69a0624af0413a670094c6615651.rack +0 -1
  52. data/test/fixtures/client/ac493997db62308972c208afa76f8479.rack +0 -1
  53. data/test/fixtures/client/d7fbf422c77af768552423633d0389e8.rack +0 -1
  54. data/test/fixtures/client/e2d68afe39f5531195273ea259b63916.rack +0 -1
data/Rakefile CHANGED
@@ -8,24 +8,8 @@ task :default => [:test]
8
8
 
9
9
  desc 'Run tests'
10
10
  Rake::TestTask.new(:test) do |t|
11
- ENV['ENABLE_STUBS'] = 'true'
12
- ENV['ENABLE_RECORD'] = 'false'
13
11
  t.ruby_opts = ["-rubygems"] if defined? Gem
14
12
  t.libs << "lib" << "test"
15
13
  t.pattern = 'test/**/*_test.rb'
16
14
  t.verbose = true
17
15
  end
18
-
19
- desc 'Record responses'
20
- task :record do
21
- ENV['ENABLE_RECORD'] = 'true'
22
- ENV['ENABLE_STUBS'] = 'false'
23
-
24
- Dir['test/**/*_test.rb'].each do |f|
25
- ruby("-Ilib:test", f)
26
-
27
- folder_name = f.match(/test\/(.+)_test.rb/)[1]
28
- FileUtils.mkdir_p("test/fixtures/#{folder_name}")
29
- FileUtils.mv(Dir.glob('*.rack'), "test/fixtures/#{folder_name}")
30
- end
31
- end
data/lib/podio.rb CHANGED
@@ -8,7 +8,6 @@ require 'podio/middleware/logger'
8
8
  require 'podio/middleware/oauth2'
9
9
  require 'podio/middleware/json_response'
10
10
  require 'podio/middleware/error_response'
11
- require 'podio/middleware/response_recorder'
12
11
 
13
12
  require 'podio/active_podio/base'
14
13
  require 'podio/active_podio/updatable'
@@ -71,9 +70,12 @@ module Podio
71
70
  autoload :ActivationStatus, 'podio/models/activation_status'
72
71
  autoload :Activity, 'podio/models/activity'
73
72
  autoload :AppStoreShare, 'podio/models/app_store_share'
73
+ autoload :AppStoreCategory, 'podio/models/app_store_category'
74
74
  autoload :Application, 'podio/models/application'
75
75
  autoload :ApplicationEmail, 'podio/models/application_email'
76
76
  autoload :ApplicationField, 'podio/models/application_field'
77
+ autoload :AccountProvider, 'podio/models/account_provider'
78
+ autoload :Batch, 'podio/models/batch'
77
79
  autoload :Bulletin, 'podio/models/bulletin'
78
80
  autoload :ByLine, 'podio/models/by_line'
79
81
  autoload :CalendarEvent, 'podio/models/calendar_event'
@@ -102,8 +104,7 @@ module Podio
102
104
  autoload :ItemField, 'podio/models/item_field'
103
105
  autoload :ItemRevision, 'podio/models/item_revision'
104
106
  autoload :LinkedAccount, 'podio/models/linked_account'
105
- autoload :Meeting, 'podio/models/meeting'
106
- autoload :MeetingParticipant, 'podio/models/meeting_participiant'
107
+ autoload :LinkedAccountData, 'podio/models/linked_account_data'
107
108
  autoload :News, 'podio/models/news'
108
109
  autoload :Notification, 'podio/models/notification'
109
110
  autoload :NotificationGroup, 'podio/models/notification_group'
@@ -119,6 +120,7 @@ module Podio
119
120
  autoload :QuestionOption, 'podio/models/question_option'
120
121
  autoload :Rating, 'podio/models/rating'
121
122
  autoload :Recurrence, 'podio/models/recurrence'
123
+ autoload :Reference, 'podio/models/reference'
122
124
  autoload :Referral, 'podio/models/referral'
123
125
  autoload :Reminder, 'podio/models/reminder'
124
126
  autoload :Search, 'podio/models/search'
@@ -138,6 +140,7 @@ module Podio
138
140
  autoload :UserMail, 'podio/models/user_mail'
139
141
  autoload :UserStatus, 'podio/models/user_status'
140
142
  autoload :Via, 'podio/models/via'
143
+ autoload :View, 'podio/models/view'
141
144
  autoload :Widget, 'podio/models/widget'
142
145
 
143
146
  end
@@ -6,27 +6,35 @@ module ActivePodio
6
6
  extend ActiveModel::Naming, ActiveModel::Callbacks
7
7
  include ActiveModel::Conversion
8
8
 
9
- class_attribute :valid_attributes, :_associations, :_properties
9
+ class_attribute :valid_attributes, :_associations, :_properties, :json_attributes
10
10
  attr_accessor :attributes, :error_code, :error_message, :error_parameters, :error_propagate
11
11
  alias_method :propagate_error?, :error_propagate
12
12
 
13
13
  def initialize(attributes = {}, options = {})
14
14
  self.valid_attributes ||= []
15
- attributes ||= {}
15
+ attributes = {} if attributes.blank?
16
16
  self.attributes = Hash[*self.valid_attributes.collect { |n| [n.to_sym, nil] }.flatten].merge(attributes.symbolize_keys)
17
17
 
18
18
  @values_from_api = options[:values_from_api] # Used to determine if date times should be converted from local to utc, or are already utc
19
19
 
20
+ self.initialize_attributes(attributes)
21
+
22
+ @belongs_to = options[:belongs_to] # Allows has_one associations to communicate their changed content back to their parent model
23
+ @values_from_api = false
24
+ end
25
+
26
+ def initialize_attributes(attributes)
20
27
  attributes.each do |key, value|
21
28
  if self.respond_to?("#{key}=".to_sym)
22
29
  self.send("#{key}=".to_sym, value)
23
30
  else
24
- is_association_hash = value.is_a?(Hash) && self._associations.present? && self._associations.has_key?(key.to_sym) && self._associations[key.to_sym] == :has_one && self.send(key.to_sym).respond_to?(:attributes)
31
+ is_association_hash = value.is_a?(Hash) && self._associations.present? && self._associations.has_key?(key.to_sym) && self._associations[key.to_sym] == :has_one && (self.send(key.to_sym).respond_to?(:attributes) || self.send(key.to_sym).nil?)
25
32
  if valid_attributes.include?(key.to_sym) || is_association_hash
26
33
  # Initialize nested object to get correctly casted values set back, unless the given values are all blank
27
34
  if is_association_hash
28
- attributes = self.send(key.to_sym).attributes
29
- if any_values_present_recursive?(attributes.values)
35
+ self.send(:[]=, key.to_sym, value) if self.send(key.to_sym).nil? # If not set by constructor, set here to get typed values back
36
+ attributes = self.send(key.to_sym).try(:attributes)
37
+ if attributes.present? && any_values_present_recursive?(attributes.values)
30
38
  value = attributes
31
39
  else
32
40
  value = nil
@@ -36,9 +44,6 @@ module ActivePodio
36
44
  end
37
45
  end
38
46
  end
39
-
40
- @belongs_to = options[:belongs_to] # Allows has_one associations to communicate their changed content back to their parent model
41
- @values_from_api = false
42
47
  end
43
48
 
44
49
  def persisted?
@@ -84,7 +89,7 @@ module ActivePodio
84
89
  result.merge!(:id => self.id) if self.respond_to?(:id)
85
90
 
86
91
  if options[:formatted]
87
- self.valid_attributes.each do |name|
92
+ (self.valid_attributes + (self.json_attributes || [])).uniq.each do |name|
88
93
  result[name] = json_friendly_value(self.send(name), options)
89
94
  end
90
95
 
@@ -123,12 +128,8 @@ module ActivePodio
123
128
  def klass_for_association(options)
124
129
  klass_name = options[:class]
125
130
  raise "Missing class name of associated model. Provide with :class => 'MyClass'." unless klass_name.present?
126
- klass = nil
127
- begin
128
- klass = klass_name.constantize
129
- rescue
130
- klass = "Podio::#{klass_name}".constantize
131
- end
131
+ klass = klass_name.constantize rescue nil
132
+ klass = "Podio::#{klass_name}".constantize unless klass.respond_to?(:ancestors) && klass.ancestors.include?(ActivePodio::Base)
132
133
  return klass
133
134
  end
134
135
 
@@ -147,8 +148,17 @@ module ActivePodio
147
148
  json_value = case ruby_value.class.name
148
149
  when "DateTime", "Time"
149
150
  ruby_value.iso8601
150
- else
151
+ when "Array"
152
+ ruby_value.collect { |rv| json_friendly_value(rv, options) }
153
+ when "Hash"
154
+ ruby_value.each { |key, value| ruby_value[key] = json_friendly_value(value, options) }
151
155
  ruby_value
156
+ else
157
+ if ruby_value.kind_of?(ActivePodio::Base)
158
+ ruby_value.as_json(options)
159
+ else
160
+ ruby_value
161
+ end
152
162
  end
153
163
  else
154
164
  ruby_value
@@ -169,6 +179,8 @@ module ActivePodio
169
179
  define_datetime_accessor(name, options)
170
180
  when :date
171
181
  define_date_accessor(name)
182
+ when :time
183
+ define_time_accessor(name)
172
184
  when :integer
173
185
  define_integer_accessor(name)
174
186
  when :boolean
@@ -216,7 +228,7 @@ module ActivePodio
216
228
  instances = self.instance_variable_get("@#{name}_has_many_instances")
217
229
  unless instances.present?
218
230
  property = options[:property] || name.to_sym
219
- if self[property].present?
231
+ if self[property].present? && self[property].respond_to?(:map)
220
232
  instances = self[property].map { |attributes| klass.new(attributes) }
221
233
  self.instance_variable_set("@#{name}_has_many_instances", instances)
222
234
  else
@@ -306,6 +318,11 @@ module ActivePodio
306
318
  end
307
319
  end
308
320
 
321
+ def output_attribute_as_json(*attributes)
322
+ self.json_attributes ||= []
323
+ self.json_attributes += attributes
324
+ end
325
+
309
326
  private
310
327
 
311
328
  def define_generic_accessor(name, options = {})
@@ -344,14 +361,14 @@ module ActivePodio
344
361
  self[name.to_sym] = if value.is_a?(DateTime)
345
362
  value.try(:to_s, :db)
346
363
  else
347
- value.try(:to_s)
364
+ value.try(:to_s).try(:presence)
348
365
  end
349
366
  end
350
367
  end
351
368
 
352
369
  def define_date_accessor(name)
353
370
  self.send(:define_method, name) do
354
- self[name.to_sym].try(:to_date)
371
+ self[name.to_sym].try(:to_date) rescue nil
355
372
  end
356
373
 
357
374
  self.send(:define_method, "#{name}=") do |value|
@@ -361,14 +378,29 @@ module ActivePodio
361
378
  value = value.try(:to_s)
362
379
  if defined?(I18n) && value.present? && !(value =~ /^\d{4}-\d{2}-\d{2}$/) # If we have I18n available, assume that we are in Rails and try to convert the string to a date to convert it to ISO 8601
363
380
  value_as_date = Date.strptime(value, I18n.t('date.formats.default')) rescue nil
364
- value_as_date.nil? ? value.try(:to_s) : value_as_date.try(:to_s, :db)
381
+ value_as_date.nil? ? value : value_as_date.try(:to_s, :db)
365
382
  else
366
- value
383
+ value.try(:presence)
367
384
  end
368
385
  end
369
386
  end
370
387
  end
371
388
 
389
+ def define_time_accessor(name)
390
+ self.send(:define_method, name) do
391
+ self[name.to_sym]
392
+ end
393
+
394
+ self.send(:define_method, "#{name}=") do |value|
395
+ time = if value.is_a?(DateTime) || value.is_a?(Time)
396
+ value
397
+ else
398
+ Time.strptime(value, I18n.t('time.formats.timeonly')) rescue Time.strptime(value, '%H:%M:%S') rescue value
399
+ end
400
+ self[name.to_sym] = time.respond_to?(:strftime) ? time.strftime('%H:%M') : time.presence
401
+ end
402
+ end
403
+
372
404
  def define_integer_accessor(name)
373
405
  self.send(:define_method, name) do
374
406
  if self[name.to_sym].present?
@@ -1,22 +1,17 @@
1
1
  # Adds functionality related to updating to an +ActivePodio+ model
2
2
  module ActivePodio
3
3
  module Updatable
4
- extend ActiveSupport::Concern
5
-
6
- module InstanceMethods
7
- def update_attributes(attributes)
8
- attributes.each do |key, value|
9
- self.send("#{key}=".to_sym, value.presence)
10
- end
4
+ def update_attributes(attributes)
5
+ attributes.each do |key, value|
6
+ self.send("#{key}=".to_sym, value.presence)
11
7
  end
8
+ end
12
9
 
13
- def remove_nil_values(input_hash)
14
- input_hash.inject({}) do |hash, (key, value)|
15
- hash[key] = value if value.present?
16
- hash
17
- end
10
+ def remove_nil_values(input_hash)
11
+ input_hash.inject({}) do |hash, (key, value)|
12
+ hash[key] = value unless value.nil?
13
+ hash
18
14
  end
19
15
  end
20
-
21
16
  end
22
- end
17
+ end
data/lib/podio/client.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Podio
2
2
  class Client
3
- attr_reader :api_url, :api_key, :api_secret, :oauth_token, :connection, :raw_connection
4
- attr_accessor :stubs, :current_http_client
3
+ attr_reader :api_url, :api_key, :api_secret, :oauth_token, :connection, :trusted_connection
4
+ attr_accessor :stubs, :current_http_client, :headers
5
5
 
6
6
  def initialize(options = {})
7
7
  @api_url = options[:api_url] || 'https://api.podio.com'
@@ -17,7 +17,6 @@ module Podio
17
17
  @stubs = Faraday::Adapter::Test::Stubs.new
18
18
  end
19
19
  @test_mode = options[:test_mode]
20
- @record_mode = options[:record_mode]
21
20
 
22
21
  setup_connections
23
22
  end
@@ -42,7 +41,9 @@ module Podio
42
41
  # sign in as a user using the server side flow
43
42
  def authenticate_with_auth_code(authorization_code, redirect_uri)
44
43
  response = @oauth_connection.post do |req|
45
- req.url '/oauth/token', :grant_type => 'authorization_code', :client_id => api_key, :client_secret => api_secret, :code => authorization_code, :redirect_uri => redirect_uri
44
+ req.url '/oauth/token'
45
+ req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
46
+ req.body = {:grant_type => 'authorization_code', :client_id => api_key, :client_secret => api_secret, :code => authorization_code, :redirect_uri => redirect_uri}
46
47
  end
47
48
 
48
49
  @oauth_token = OAuthToken.new(response.body)
@@ -53,7 +54,9 @@ module Podio
53
54
  # Sign in as a user using credentials
54
55
  def authenticate_with_credentials(username, password)
55
56
  response = @oauth_connection.post do |req|
56
- req.url '/oauth/token', :grant_type => 'password', :client_id => api_key, :client_secret => api_secret, :username => username, :password => password
57
+ req.url '/oauth/token'
58
+ req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
59
+ req.body = {:grant_type => 'password', :client_id => api_key, :client_secret => api_secret, :username => username, :password => password}
57
60
  end
58
61
 
59
62
  @oauth_token = OAuthToken.new(response.body)
@@ -64,7 +67,22 @@ module Podio
64
67
  # Sign in as an app
65
68
  def authenticate_with_app(app_id, app_token)
66
69
  response = @oauth_connection.post do |req|
67
- req.url '/oauth/token', :grant_type => 'app', :client_id => api_key, :client_secret => api_secret, :app_id => app_id, :app_token => app_token
70
+ req.url '/oauth/token'
71
+ req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
72
+ req.body = {:grant_type => 'app', :client_id => api_key, :client_secret => api_secret, :app_id => app_id, :app_token => app_token}
73
+ end
74
+
75
+ @oauth_token = OAuthToken.new(response.body)
76
+ configure_oauth
77
+ @oauth_token
78
+ end
79
+
80
+ # Sign in with an transfer token, only available for Podio
81
+ def authenticate_with_transfer_token(transfer_token)
82
+ response = @oauth_connection.post do |req|
83
+ req.url '/oauth/token'
84
+ req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
85
+ req.body = {:grant_type => 'transfer_token', :client_id => api_key, :client_secret => api_secret, :transfer_token => transfer_token}
68
86
  end
69
87
 
70
88
  @oauth_token = OAuthToken.new(response.body)
@@ -81,14 +99,15 @@ module Podio
81
99
 
82
100
  @oauth_token = OAuthToken.new(response.body)
83
101
  configure_oauth
84
-
85
- [@oauth_token, response['new_user_created']]
102
+ [@oauth_token, response.body['new_user_created']]
86
103
  end
87
104
 
88
105
  # Sign in with an OpenID, only available for Podio
89
106
  def authenticate_with_openid(identifier, type)
90
107
  response = @oauth_connection.post do |req|
91
- req.url '/oauth/token_by_openid', :grant_type => type, :client_id => api_key, :client_secret => api_secret, :identifier => identifier
108
+ req.url '/oauth/token_by_openid'
109
+ req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
110
+ req.body = {:grant_type => type, :client_id => api_key, :client_secret => api_secret, :identifier => identifier}
92
111
  end
93
112
 
94
113
  @oauth_token = OAuthToken.new(response.body)
@@ -96,6 +115,7 @@ module Podio
96
115
  @oauth_token
97
116
  end
98
117
 
118
+ # reconfigure the client with a different access token
99
119
  def oauth_token=(new_oauth_token)
100
120
  @oauth_token = new_oauth_token.is_a?(Hash) ? OAuthToken.new(new_oauth_token) : new_oauth_token
101
121
  configure_oauth
@@ -103,7 +123,9 @@ module Podio
103
123
 
104
124
  def refresh_access_token
105
125
  response = @oauth_connection.post do |req|
106
- req.url '/oauth/token', :grant_type => 'refresh_token', :refresh_token => oauth_token.refresh_token, :client_id => api_key, :client_secret => api_secret
126
+ req.url '/oauth/token'
127
+ req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
128
+ req.body = {:grant_type => 'refresh_token', :refresh_token => oauth_token.refresh_token, :client_id => api_key, :client_secret => api_secret}
107
129
  end
108
130
 
109
131
  @oauth_token = OAuthToken.new(response.body)
@@ -115,7 +137,7 @@ module Podio
115
137
  headers = @headers.dup
116
138
  headers['User-Agent'] = 'Podio Ruby Library'
117
139
  headers['authorization'] = "OAuth2 #{oauth_token.access_token}" if oauth_token
118
- headers['X-Podio-Dry-Run'] = @test_mode if @test_mode
140
+ headers['X-Podio-Dry-Run'] = @test_mode.to_s if @test_mode
119
141
 
120
142
  headers
121
143
  end
@@ -124,14 +146,15 @@ module Podio
124
146
 
125
147
  def setup_connections
126
148
  @connection = configure_connection
127
- @raw_connection = configure_connection(true)
128
149
  @oauth_connection = configure_oauth_connection
150
+ @trusted_connection = configure_trusted_connection
129
151
  end
130
152
 
131
- def configure_connection(raw=false)
153
+ def configure_connection
132
154
  Faraday::Connection.new(:url => api_url, :headers => configured_headers, :request => {:client => self}) do |builder|
133
- builder.use Middleware::JsonRequest unless raw
134
- builder.use Faraday::Request::Multipart if raw
155
+ builder.use Middleware::JsonRequest
156
+ builder.use Faraday::Request::Multipart
157
+ builder.use Faraday::Request::UrlEncoded
135
158
  builder.use Middleware::OAuth2
136
159
  builder.use Middleware::Logger
137
160
 
@@ -141,7 +164,6 @@ module Podio
141
164
  # builder.use Middleware::DateConversion
142
165
  builder.use Middleware::ErrorResponse
143
166
  builder.use Middleware::JsonResponse
144
- builder.use Middleware::ResponseRecorder if @record_mode
145
167
  end
146
168
  end
147
169
 
@@ -157,9 +179,16 @@ module Podio
157
179
  conn
158
180
  end
159
181
 
182
+ def configure_trusted_connection
183
+ conn = @connection.dup
184
+ conn.options[:client] = self
185
+ conn.headers.delete('authorization')
186
+ conn.basic_auth(api_key, api_secret)
187
+ conn
188
+ end
189
+
160
190
  def configure_oauth
161
191
  @connection = configure_connection
162
- @raw_connection = configure_connection(true)
163
192
  end
164
193
  end
165
194
  end
data/lib/podio/error.rb CHANGED
@@ -19,4 +19,13 @@ module Podio
19
19
  class GoneError < PodioError; end
20
20
  class RateLimitError < PodioError; end
21
21
  class UnavailableError < PodioError; end
22
+
23
+ class RequestableAuthorizationError < AuthorizationError
24
+ attr_reader :request_access_info
25
+
26
+ def initialize(response_body, response_status, url)
27
+ @request_access_info = response_body['error_parameters']
28
+ super
29
+ end
30
+ end
22
31
  end
@@ -20,7 +20,11 @@ module Podio
20
20
  raise AuthorizationError.new(env[:body], env[:status], env[:url])
21
21
  end
22
22
  when 403
23
- raise AuthorizationError.new(env[:body], env[:status], env[:url])
23
+ if env[:body]['error'] == 'requestable_forbidden'
24
+ raise RequestableAuthorizationError.new(env[:body], env[:status], env[:url])
25
+ else
26
+ raise AuthorizationError.new(env[:body], env[:status], env[:url])
27
+ end
24
28
  when 404
25
29
  raise NotFoundError.new(env[:body], env[:status], env[:url])
26
30
  when 409