openstax_api 8.3.2 → 9.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7296239fd11318616e99546c687c2f99a387e17425f0f6efca8f6b4f77059fc6
4
- data.tar.gz: 0dcbc6e75158fda3afe0ded916182726a285d6bf565ac1bb131b4115290bcebc
3
+ metadata.gz: aec2631a5eebf6c105ae15fa8462c06577027583db6b2cbaa952aea4acf52280
4
+ data.tar.gz: 3d0ee92a6bdaa1e01f9040dd62fb8b65be37c30262f678aeda4e9ec6a8324f88
5
5
  SHA512:
6
- metadata.gz: 3296d8f4e8354e4fb26ebd43d75ce509160a2c2d4b1a74c245b111514431ce50f9bc330f1eb8ba49975f7db00d592f81a7374bd0fe98303b7fb6341144b9d6b3
7
- data.tar.gz: 6483a27055e0b8f01850dd77cf22ecfe39ffb3d74d9a41ef2bbd52ece5fda56754d0ea50fd2a8c0c259b57a8f4129d4fb7739cedc453dfe955f8e0bbf95aab84
6
+ metadata.gz: 9d01d88bad42186d009a46dc9030399c9c36542a170a3d8f711ea03dedc4f09548da45ecf6f75c39bb22f3553efb4f4f7a050335e5290cf475dcaa37f7b9a326
7
+ data.tar.gz: c796fbdfde096f09fea43bb50091e6df8137d5d82064d3357c661506a73cc312c15c044aceec6b66ebc6616f7d57f4d11c189c4fd20282af9c84c03ddcbd5bce
data/Rakefile CHANGED
@@ -17,4 +17,4 @@ require 'rspec/core/rake_task'
17
17
  desc 'Run all specs in spec directory (excluding plugin specs)'
18
18
  RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
19
19
 
20
- task :default => :spec
20
+ task default: :spec
@@ -12,27 +12,27 @@ module OpenStax
12
12
 
13
13
  respond_to :json
14
14
 
15
- # after_filters are in place to make sure certain things are set how we
16
- # want even if something else goes on during the request. These filters
17
- # are also paired with before_filters in case an exception prevents
15
+ # after_actions are in place to make sure certain things are set how we
16
+ # want even if something else goes on during the request. These actions
17
+ # are also paired with before_actions in case an exception prevents
18
18
  # normal action completion.
19
19
 
20
20
  # Always force JSON requests and send the Date header in the response
21
- before_filter :force_json_content_type
22
- before_filter :set_date_header
23
- after_filter :set_date_header
21
+ before_action :force_json_content_type
22
+ before_action :set_date_header
23
+ after_action :set_date_header
24
24
 
25
25
  # Doorkeeper is used only if a token is present
26
26
  # Access policies should be used to limit access to anonymous users
27
- before_filter :doorkeeper_authorize!, if: :token_user?
27
+ before_action :doorkeeper_authorize!, if: :token_user?
28
28
 
29
29
  # Except for users logged in via a cookie, we can disable CSRF protection and enable CORS
30
- skip_before_filter :verify_authenticity_token, unless: :local_session_user?
31
- skip_before_filter :authenticate_user!, only: :options
32
- skip_before_filter :verify_authenticity_token, only: :options
30
+ skip_before_action :verify_authenticity_token, unless: :local_session_user?
31
+ skip_before_action :verify_authenticity_token, only: :options
32
+ skip_before_action :authenticate_user!, only: :options, raise: false
33
33
 
34
- before_filter :maybe_set_cors_headers
35
- after_filter :maybe_set_cors_headers
34
+ before_action :maybe_set_cors_headers
35
+ after_action :maybe_set_cors_headers
36
36
 
37
37
  # Keep old current_user method so we can use it
38
38
  alias_method :current_session_user, OpenStax::Api.configuration.current_user_method
@@ -40,6 +40,11 @@ module OpenStax
40
40
  # Ensure we will never again confuse human users and api users
41
41
  undef_method OpenStax::Api.configuration.current_user_method
42
42
 
43
+ # intended to be overridden by parent
44
+ def authenticate_user!
45
+ throw(:abort)
46
+ end
47
+
43
48
  # Always return an ApiUser
44
49
  def current_api_user
45
50
  @current_api_user ||= ApiUser.new(doorkeeper_token, lambda { current_session_user })
@@ -13,6 +13,8 @@ module OpenStax
13
13
  class Engine < ::Rails::Engine
14
14
  isolate_namespace OpenStax::Api
15
15
 
16
+ config.autoload_paths += Dir[config.root.join('app', 'representers', '{**}')]
17
+
16
18
  config.generators do |g|
17
19
  g.test_framework :rspec, fixture: false
18
20
  g.fixture_replacement :factory_bot, dir: 'spec/factories'
@@ -13,7 +13,7 @@ module OpenStax
13
13
  model_klass = relation.base_class
14
14
  OSU::AccessPolicy.require_action_allowed!(:index, current_api_user, model_klass)
15
15
 
16
- represent_with_options = { user_options: options }.merge(represent_with: represent_with)
16
+ represent_with_options = { user_options: options, represent_with: represent_with }
17
17
 
18
18
  relation.each do |item|
19
19
  # Must be able to read each record
@@ -24,11 +24,10 @@ module OpenStax
24
24
  end
25
25
 
26
26
  def standard_search(klass, routine, represent_with, options={})
27
- search_options = { location: nil }
28
27
  user = current_api_user
29
28
  OSU::AccessPolicy.require_action_allowed!(:search, user, klass)
30
29
 
31
- represent_with_options = { user_options: options }.merge(represent_with: represent_with)
30
+ represent_with_options = { user_options: options, represent_with: represent_with }
32
31
 
33
32
  result = routine.call(params, options)
34
33
  return render_api_errors(result.errors) if result.errors.any?
@@ -38,12 +37,11 @@ module OpenStax
38
37
  OSU::AccessPolicy.require_action_allowed!(:read, user, item)
39
38
  end
40
39
 
41
- respond_with outputs, search_options.merge(represent_with_options)
40
+ respond_with outputs, { status: :ok, location: nil }.merge(represent_with_options)
42
41
  end
43
42
 
44
43
  def standard_create(model, represent_with=nil, options={})
45
- create_options = { status: :created, location: nil }
46
- represent_with_options = { user_options: options }.merge(represent_with: represent_with)
44
+ represent_with_options = { user_options: options, represent_with: represent_with }
47
45
 
48
46
  model.class.transaction do
49
47
  consume!(model, represent_with_options.dup)
@@ -51,7 +49,7 @@ module OpenStax
51
49
  OSU::AccessPolicy.require_action_allowed!(:create, current_api_user, model)
52
50
 
53
51
  if model.save
54
- respond_with model, create_options.merge(represent_with_options)
52
+ respond_with model, { status: :created, location: nil }.merge(represent_with_options)
55
53
  else
56
54
  render_api_errors(model.errors)
57
55
  end
@@ -71,9 +69,7 @@ module OpenStax
71
69
  def standard_read(model, represent_with=nil, use_timestamp_for_cache=false, options={})
72
70
  OSU::AccessPolicy.require_action_allowed!(:read, current_api_user, model)
73
71
 
74
- represent_with_options = { user_options: options }.merge(represent_with: represent_with)
75
-
76
- respond_with model, represent_with_options \
72
+ respond_with(model, { user_options: options, represent_with: represent_with }) \
77
73
  if !use_timestamp_for_cache || stale?(model, template: false)
78
74
  end
79
75
 
@@ -82,7 +78,7 @@ module OpenStax
82
78
  OSU::AccessPolicy.require_action_allowed!(:update, current_api_user, model)
83
79
 
84
80
  responder_options = { responder: ResponderWithPutPatchDeleteContent }
85
- represent_with_options = { user_options: options }.merge(represent_with: represent_with)
81
+ represent_with_options = { user_options: options, represent_with: represent_with }
86
82
 
87
83
  model.with_lock do
88
84
  consume!(model, represent_with_options.dup)
@@ -106,11 +102,12 @@ module OpenStax
106
102
  if model.respond_to?(:deleted?) && model.deleted?
107
103
 
108
104
  responder_options = { responder: ResponderWithPutPatchDeleteContent }
109
- represent_with_options = { user_options: options }.merge(represent_with: represent_with)
105
+ represent_with_options = { user_options: options, represent_with: represent_with }
110
106
 
111
107
  model.with_lock do
112
108
  if model.destroy
113
- model.clear_association_cache
109
+ model.send :clear_association_cache
110
+ yield model if block_given?
114
111
  respond_with model, responder_options.merge(represent_with_options)
115
112
  else
116
113
  render_api_errors(model.errors)
@@ -128,12 +125,14 @@ module OpenStax
128
125
  recursive = options.has_key?(:recursive) ? options[:recursive] : true
129
126
 
130
127
  responder_options = { responder: ResponderWithPutPatchDeleteContent }
131
- represent_with_options = { user_options: options.except(:recursive) }
132
- .merge(represent_with: represent_with)
128
+ represent_with_options = {
129
+ user_options: options.except(:recursive), represent_with: represent_with
130
+ }
133
131
 
134
132
  model.with_lock do
135
133
  if model.restore(recursive: recursive)
136
- model.clear_association_cache
134
+ model.send :clear_association_cache
135
+ yield model if block_given?
137
136
  respond_with model, responder_options.merge(represent_with_options)
138
137
  else
139
138
  render_api_errors(model.errors)
@@ -1,11 +1,15 @@
1
1
  # Provides API-specific HTTP request methods
2
2
  #
3
- # The args at the end of each request is interpreted a hash that can contain
4
- # keys for:
5
- # :raw_post_data -- a JSON string (if a Hash provided, to_json will be called on it)
6
- # :parameters -- a hash of parameters
7
- # :session -- whatever built-in request methods expect
8
- # :flash -- whatever built-in request methods expect
3
+ # action is a symbol (controller specs) OR a relative url (request specs)
4
+ #
5
+ # doorkeeper_token is a Doorkeeper::AccessToken or nil
6
+ #
7
+ # args are a hash that can contain the following keys:
8
+ # :params -- a hash of parameters (controller specs) OR a json string (request specs)
9
+ # :body -- a JSON string (controller specs only)
10
+ # :format -- always set to :json for API calls
11
+ # :session, :flash -- hashes (controller specs)
12
+ # :headers, :env -- hashes (request specs)
9
13
  #
10
14
  # Helpful documentation:
11
15
  # https://github.com/rails/rails/blob/3-2-stable/actionpack/lib/action_controller/test_case.rb
@@ -13,71 +17,67 @@
13
17
  module OpenStax
14
18
  module Api
15
19
  module RSpecHelpers
16
-
17
- def api_get(action, doorkeeper_token, args={})
20
+ def api_get(action, doorkeeper_token = nil, args={})
18
21
  api_request(:get, action, doorkeeper_token, args)
19
22
  end
20
23
 
21
- def api_put(action, doorkeeper_token, args={})
24
+ def api_put(action, doorkeeper_token = nil, args={})
22
25
  api_request(:put, action, doorkeeper_token, args)
23
26
  end
24
27
 
25
- def api_post(action, doorkeeper_token, args={})
28
+ def api_post(action, doorkeeper_token = nil, args={})
26
29
  api_request(:post, action, doorkeeper_token, args)
27
30
  end
28
31
 
29
- def api_delete(action, doorkeeper_token, args={})
32
+ def api_delete(action, doorkeeper_token = nil, args={})
30
33
  api_request(:delete, action, doorkeeper_token, args)
31
34
  end
32
35
 
33
- def api_patch(action, doorkeeper_token, args={})
36
+ def api_patch(action, doorkeeper_token = nil, args={})
34
37
  api_request(:patch, action, doorkeeper_token, args)
35
38
  end
36
39
 
37
- def api_head(action, doorkeeper_token, args={})
40
+ def api_head(action, doorkeeper_token = nil, args={})
38
41
  api_request(:head, action, doorkeeper_token, args)
39
42
  end
40
43
 
41
- def api_request(type, action, doorkeeper_token, args={})
42
- raise IllegalArgument if ![:get, :post, :put, :delete, :patch, :head].include?(type)
43
-
44
- header = is_a_controller_spec? ? request.env : {}
44
+ def api_request(type, action, doorkeeper_token = nil, args={})
45
+ raise IllegalArgument unless [:head, :get, :post, :patch, :put, :delete].include?(type)
45
46
 
46
- # Add the doorkeeper token info
47
- header['HTTP_AUTHORIZATION'] = "Bearer #{doorkeeper_token.token}" \
48
- if doorkeeper_token
47
+ headers = is_a_controller_spec? ? request.headers : {}
49
48
 
50
49
  # Select the version of the API based on the spec metadata and populate the accept header
51
50
  version_string = self.class.metadata[:version].try(:to_s)
52
- raise ArgumentError, "Top-level 'describe' metadata must include a value for ':version'" if version_string.nil?
53
- header['HTTP_ACCEPT'] = "application/vnd.openstax.#{version_string}"
54
-
55
- # Set the raw post data in the request, converting to JSON if needed
56
- if args[:raw_post_data]
57
- header['RAW_POST_DATA'] = args[:raw_post_data].is_a?(Hash) ?
58
- args[:raw_post_data].to_json :
59
- args[:raw_post_data]
60
- end
51
+ raise ArgumentError, "Top-level 'describe' metadata must include a value for ':version'" \
52
+ if version_string.nil?
53
+ headers['HTTP_ACCEPT'] = "application/vnd.openstax.#{version_string}"
54
+
55
+ # Add the doorkeeper token header
56
+ headers['HTTP_AUTHORIZATION'] = "Bearer #{doorkeeper_token.token}" \
57
+ if doorkeeper_token
61
58
 
62
- # Set the data format
63
- args[:parameters] ||= {}
64
- args[:parameters][:format] = 'json'
65
- header['CONTENT_TYPE'] = 'application/json'
59
+ headers['CONTENT_TYPE'] = 'application/json'
60
+
61
+ if is_a_controller_spec?
62
+ request.headers.merge! headers
63
+ args[:format] = :json
64
+ # Convert the request body to JSON if needed
65
+ args[:body] = args[:body].to_json unless args[:body].nil? || args[:body].is_a?(String)
66
+ else
67
+ args[:headers] = headers
68
+ end
66
69
 
67
70
  # If these helpers are used from a request spec, action can
68
71
  # be a URL fragment string -- in such a case, prepend "/api"
69
72
  # to the front of the URL as a convenience to callers
70
73
 
71
- if action.is_a? String
72
- action = "/#{action}" if !action.starts_with?("/")
73
- action = "/api#{action}" if !action.starts_with?("/api/")
74
+ action = action.to_s unless is_a_controller_spec?
75
+ if action.is_a?(String) && !action.include?('://')
76
+ action = "/#{action}" if !action.starts_with?('/')
77
+ action = "/api#{action}" if !action.starts_with?('/api/')
74
78
  end
75
79
 
76
- if is_a_controller_spec?
77
- send(type, action, args[:parameters], args[:session], args[:flash])
78
- else
79
- send(type, action, args[:parameters].to_json, header)
80
- end
80
+ send type, action, args
81
81
  end
82
82
 
83
83
  private
@@ -85,7 +85,6 @@ module OpenStax
85
85
  def is_a_controller_spec?
86
86
  self.class.metadata[:type] == :controller
87
87
  end
88
-
89
88
  end
90
89
  end
91
90
  end
@@ -1,5 +1,5 @@
1
1
  module OpenStax
2
2
  module Api
3
- VERSION = "8.3.2"
3
+ VERSION = '9.3.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openstax_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.3.2
4
+ version: 9.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dante Soares
@@ -9,146 +9,134 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-11-28 00:00:00.000000000 Z
12
+ date: 2020-09-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ">="
19
- - !ruby/object:Gem::Version
20
- version: '3.1'
21
- - - "<"
18
+ - - "~>"
22
19
  - !ruby/object:Gem::Version
23
- version: '5.0'
20
+ version: '5.2'
24
21
  type: :runtime
25
22
  prerelease: false
26
23
  version_requirements: !ruby/object:Gem::Requirement
27
24
  requirements:
28
- - - ">="
29
- - !ruby/object:Gem::Version
30
- version: '3.1'
31
- - - "<"
25
+ - - "~>"
32
26
  - !ruby/object:Gem::Version
33
- version: '5.0'
27
+ version: '5.2'
34
28
  - !ruby/object:Gem::Dependency
35
29
  name: representable
36
30
  requirement: !ruby/object:Gem::Requirement
37
31
  requirements:
38
32
  - - ">="
39
33
  - !ruby/object:Gem::Version
40
- version: '2.4'
41
- - - "<"
42
- - !ruby/object:Gem::Version
43
- version: '4.0'
34
+ version: '0'
44
35
  type: :runtime
45
36
  prerelease: false
46
37
  version_requirements: !ruby/object:Gem::Requirement
47
38
  requirements:
48
39
  - - ">="
49
40
  - !ruby/object:Gem::Version
50
- version: '2.4'
51
- - - "<"
52
- - !ruby/object:Gem::Version
53
- version: '4.0'
41
+ version: '0'
54
42
  - !ruby/object:Gem::Dependency
55
43
  name: roar
56
44
  requirement: !ruby/object:Gem::Requirement
57
45
  requirements:
58
46
  - - ">="
59
47
  - !ruby/object:Gem::Version
60
- version: '1.0'
48
+ version: '0'
61
49
  type: :runtime
62
50
  prerelease: false
63
51
  version_requirements: !ruby/object:Gem::Requirement
64
52
  requirements:
65
53
  - - ">="
66
54
  - !ruby/object:Gem::Version
67
- version: '1.0'
55
+ version: '0'
68
56
  - !ruby/object:Gem::Dependency
69
57
  name: roar-rails
70
58
  requirement: !ruby/object:Gem::Requirement
71
59
  requirements:
72
60
  - - ">="
73
61
  - !ruby/object:Gem::Version
74
- version: '1.0'
62
+ version: '0'
75
63
  type: :runtime
76
64
  prerelease: false
77
65
  version_requirements: !ruby/object:Gem::Requirement
78
66
  requirements:
79
67
  - - ">="
80
68
  - !ruby/object:Gem::Version
81
- version: '1.0'
69
+ version: '0'
82
70
  - !ruby/object:Gem::Dependency
83
71
  name: uber
84
72
  requirement: !ruby/object:Gem::Requirement
85
73
  requirements:
86
- - - "<"
74
+ - - ">="
87
75
  - !ruby/object:Gem::Version
88
- version: 0.1.0
76
+ version: '0'
89
77
  type: :runtime
90
78
  prerelease: false
91
79
  version_requirements: !ruby/object:Gem::Requirement
92
80
  requirements:
93
- - - "<"
81
+ - - ">="
94
82
  - !ruby/object:Gem::Version
95
- version: 0.1.0
83
+ version: '0'
96
84
  - !ruby/object:Gem::Dependency
97
85
  name: doorkeeper
98
86
  requirement: !ruby/object:Gem::Requirement
99
87
  requirements:
100
88
  - - ">="
101
89
  - !ruby/object:Gem::Version
102
- version: '2.0'
90
+ version: '0'
103
91
  type: :runtime
104
92
  prerelease: false
105
93
  version_requirements: !ruby/object:Gem::Requirement
106
94
  requirements:
107
95
  - - ">="
108
96
  - !ruby/object:Gem::Version
109
- version: '2.0'
97
+ version: '0'
110
98
  - !ruby/object:Gem::Dependency
111
99
  name: exception_notification
112
100
  requirement: !ruby/object:Gem::Requirement
113
101
  requirements:
114
102
  - - ">="
115
103
  - !ruby/object:Gem::Version
116
- version: '4.0'
104
+ version: '0'
117
105
  type: :runtime
118
106
  prerelease: false
119
107
  version_requirements: !ruby/object:Gem::Requirement
120
108
  requirements:
121
109
  - - ">="
122
110
  - !ruby/object:Gem::Version
123
- version: '4.0'
111
+ version: '0'
124
112
  - !ruby/object:Gem::Dependency
125
113
  name: openstax_utilities
126
114
  requirement: !ruby/object:Gem::Requirement
127
115
  requirements:
128
116
  - - ">="
129
117
  - !ruby/object:Gem::Version
130
- version: 4.2.0
118
+ version: '0'
131
119
  type: :runtime
132
120
  prerelease: false
133
121
  version_requirements: !ruby/object:Gem::Requirement
134
122
  requirements:
135
123
  - - ">="
136
124
  - !ruby/object:Gem::Version
137
- version: 4.2.0
125
+ version: '0'
138
126
  - !ruby/object:Gem::Dependency
139
127
  name: lev
140
128
  requirement: !ruby/object:Gem::Requirement
141
129
  requirements:
142
130
  - - ">="
143
131
  - !ruby/object:Gem::Version
144
- version: 1.0.0
132
+ version: '0'
145
133
  type: :runtime
146
134
  prerelease: false
147
135
  version_requirements: !ruby/object:Gem::Requirement
148
136
  requirements:
149
137
  - - ">="
150
138
  - !ruby/object:Gem::Version
151
- version: 1.0.0
139
+ version: '0'
152
140
  - !ruby/object:Gem::Dependency
153
141
  name: responders
154
142
  requirement: !ruby/object:Gem::Requirement
@@ -164,7 +152,7 @@ dependencies:
164
152
  - !ruby/object:Gem::Version
165
153
  version: '0'
166
154
  - !ruby/object:Gem::Dependency
167
- name: sqlite3
155
+ name: sprockets
168
156
  requirement: !ruby/object:Gem::Requirement
169
157
  requirements:
170
158
  - - ">="
@@ -178,7 +166,7 @@ dependencies:
178
166
  - !ruby/object:Gem::Version
179
167
  version: '0'
180
168
  - !ruby/object:Gem::Dependency
181
- name: rspec-rails
169
+ name: sqlite3
182
170
  requirement: !ruby/object:Gem::Requirement
183
171
  requirements:
184
172
  - - ">="
@@ -192,7 +180,7 @@ dependencies:
192
180
  - !ruby/object:Gem::Version
193
181
  version: '0'
194
182
  - !ruby/object:Gem::Dependency
195
- name: factory_bot_rails
183
+ name: rspec-rails
196
184
  requirement: !ruby/object:Gem::Requirement
197
185
  requirements:
198
186
  - - ">="
@@ -206,7 +194,7 @@ dependencies:
206
194
  - !ruby/object:Gem::Version
207
195
  version: '0'
208
196
  - !ruby/object:Gem::Dependency
209
- name: faker
197
+ name: factory_bot_rails
210
198
  requirement: !ruby/object:Gem::Requirement
211
199
  requirements:
212
200
  - - ">="
@@ -220,7 +208,7 @@ dependencies:
220
208
  - !ruby/object:Gem::Version
221
209
  version: '0'
222
210
  - !ruby/object:Gem::Dependency
223
- name: squeel
211
+ name: faker
224
212
  requirement: !ruby/object:Gem::Requirement
225
213
  requirements:
226
214
  - - ">="
@@ -294,8 +282,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
294
282
  - !ruby/object:Gem::Version
295
283
  version: '0'
296
284
  requirements: []
297
- rubyforge_project:
298
- rubygems_version: 2.7.3
285
+ rubygems_version: 3.1.4
299
286
  signing_key:
300
287
  specification_version: 4
301
288
  summary: API utilities for OpenStax products and tools.