openstax_api 8.3.2 → 9.3.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
  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.