thecore_api 1.4.2 → 1.4.3

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: 649421e70773b321338691a8393dbf79c85036a0e09e4abd4a3a48e9219cab74
4
- data.tar.gz: fd5797b1bf28846babac2bf595189e8b6d74fb062bd273227332d2d428c018c1
3
+ metadata.gz: 1af0a793ef25d9d3d8678683c1b9b016d85d41b8a206ea2a73ea7c2b8182901e
4
+ data.tar.gz: ba9b80c4635788726dcc8e4c0f25109f1c401fdda25cf59b99667846ffef97cb
5
5
  SHA512:
6
- metadata.gz: 3bb6636c2b157ca34115fcdf0830a4d8f9e4dd910f7c394f9095062a0c73ef8e17ce3b2d6766e9d89589bf6e9e5a88c8e08186eb13a713246ff1e0a0480306bf
7
- data.tar.gz: a457df07061e2c74d1c5ccd17c5f497ad8782fc7f95a28fa38725dc48bf556d2deff2ca85248a1e3745dc548002c547ac7f9cd45b92ebd367b11a4bd85fd3da6
6
+ metadata.gz: 8b96365c02d73622755d5a9ddd7ad8414eaca91188c06715cd79d7bc80d752c63578127751676c31f5b18448fb1cb48248eae3bb84455dacc2bac503855935e2
7
+ data.tar.gz: d83ebaa1e04526cb60bccade5f21c28b1078ae44acd18200d9f06ce5ac99a2c8842df8eb43da5b07b933fe95097d2ca55b53b6f7333ff5a2f41b4d27d991bd22
@@ -25,12 +25,12 @@ class Api::V1::BaseController < ActionController::API
25
25
  before_action :find_model, except: [ :version, :token, :available_roles, :check, :translations, :schema ]
26
26
  before_action :find_record, only: [ :show, :update, :destroy ]
27
27
 
28
- rescue_from ActiveRecord::RecordNotFound, with: :not_found!
29
28
  rescue_from ActiveRecord::StatementInvalid, with: :unauthenticated!
30
29
  rescue_from ActiveRecord::RecordInvalid, with: :invalid!
31
- #rescue_from CanCan::AuthorizationNotPerformed, with: :unauthorized!
32
30
  rescue_from CanCan::AccessDenied, with: :unauthorized!
33
- #rescue_from Pundit::NotAuthorizedError, with: :unauthorized!
31
+ rescue_from ActiveRecord::RecordNotFound, with: :not_found!
32
+ rescue_from NameError, with: :not_found!
33
+ rescue_from NoMethodError, with: :not_found!
34
34
 
35
35
  attr_accessor :current_user
36
36
 
@@ -40,7 +40,13 @@ class Api::V1::BaseController < ActionController::API
40
40
  # end
41
41
 
42
42
  def check
43
+ # This method is only valid for ActiveRecords
44
+ # For any other model-less controller, the actions must be
45
+ # defined in the route, and must exist in the controller definition.
46
+ # So, if it's not an activerecord, the find model makes no sense at all
47
+ # Thus must return 404
43
48
  path = params[:path].split("/")
49
+ return not_found! if (!path.first.classify.constantize.new.is_a? ActiveRecord::Base rescue false)
44
50
  find_model path.first
45
51
  if request.get?
46
52
  if path.second.blank?
@@ -51,10 +57,10 @@ class Api::V1::BaseController < ActionController::API
51
57
  @query = params[:q]
52
58
  index
53
59
  elsif path.second.to_i.zero?
54
- # String, so it's a custom action I must find in the @model (as an singleton method)
55
- # Like: :controller/:custom_action
56
- result = MultiJson.dump(@model.send(path.second, params))
57
- return render json: result, status: result.blank? ? 404 : 200
60
+ # String, so it's a custom action I must find in the @model (as a singleton method)
61
+ # GET :controller/:custom_action
62
+ return not_found! unless @model.respond_to?(path.second)
63
+ return render json: MultiJson.dump(@model.send(path.second, params)), status: 200
58
64
  elsif !path.second.to_i.zero? && path.third.blank?
59
65
  # Integer, so it's an ID, I must show it
60
66
  # Rails.logger.debug "IL SECONDO è ID? #{path.second.inspect}"
@@ -63,17 +69,18 @@ class Api::V1::BaseController < ActionController::API
63
69
  find_record
64
70
  show
65
71
  elsif !path.second.to_i.zero? && !path.third.blank?
66
- # Like :controller/:id/:custom_action
67
- result = MultiJson.dump(@model.send(path.third, path.second.to_i, params))
68
- return render json: result, status: result.blank? ? 404 : 200
72
+ # GET :controller/:id/:custom_action
73
+ return not_found! unless @model.respond_to?(path.third)
74
+ return render json: MultiJson.dump(@model.send(path.third, path.second.to_i, params)), status: 200
69
75
  end
70
76
  elsif request.post?
71
77
  if path.second.blank?
72
78
  @params = params
73
79
  create
74
80
  elsif path.second.to_i.zero?
75
- result = MultiJson.dump(@model.send(path.second, params))
76
- return render json: result, status: result.blank? ? 404 : 200
81
+ # POST :controller/:custom_action
82
+ return not_found! unless @model.respond_to?(path.second)
83
+ return render json: MultiJson.dump(@model.send(path.second, params)), status: 200
77
84
  end
78
85
  elsif request.put?
79
86
  if !path.second.to_i.zero? && path.third.blank?
@@ -84,8 +91,9 @@ class Api::V1::BaseController < ActionController::API
84
91
  find_record
85
92
  update
86
93
  elsif !path.second.to_i.zero? && !path.third.blank?
87
- result = MultiJson.dump(@model.send(path.third, path.second.to_i, params))
88
- return render json: result, status: result.blank? ? 404 : 200
94
+ # PUT :controller/:id/:custom_action
95
+ return not_found! unless @model.respond_to?(path.third)
96
+ return render json: MultiJson.dump(@model.send(path.third, path.second.to_i, params)), status: 200
89
97
  end
90
98
  elsif request.delete?
91
99
  # Rails.logger.debug "IL SECONDO è ID in delete? #{path.second.inspect}"
@@ -178,44 +186,48 @@ class Api::V1::BaseController < ActionController::API
178
186
 
179
187
  def unauthenticated!
180
188
  response.headers['WWW-Authenticate'] = "Token realm=Application"
181
- render json: { error: 'bad credentials' }, status: 401
189
+ # render json: { error: 'bad credentials' }, status: 401
190
+ api_error status: 401, errors: [I18n.t("api.errors.bad_credentials", default: "Bad Credentials")]
182
191
  end
183
192
 
184
193
  def unauthorized!
185
- render nothing: true, status: :forbidden
186
- return
187
- end
188
-
189
- def invalid_credentials!
190
- render json: { error: 'invalid credentials' }, status: 403
194
+ # render nothing: true, status: :forbidden
195
+ api_error status: 403, errors: [I18n.t("api.errors.unauthorized", default: "Unauthorized")]
191
196
  return
192
197
  end
193
198
 
194
- def unable!
195
- render json: { error: 'you are not enabled to do so' }, status: 403
199
+ def not_found!
200
+ return api_error(status: 404, errors: [I18n.t("api.errors.not_found", default: "Not Found")])
196
201
  end
197
202
 
198
203
  def invalid! exception
199
204
  # Rails.logger.debug exception.errors.inspect
200
- render json: { error: exception }, status: 422
201
- end
202
-
203
- def invalid_resource!(errors = [])
204
- api_error(status: 422, errors: errors)
205
- end
206
-
207
- def not_found!
208
- return api_error(status: 404, errors: 'Not found')
205
+ # render json: { error: exception }, status: 422
206
+ api_error status: 422, errors: exception
209
207
  end
210
208
 
211
209
  def api_error(status: 500, errors: [])
212
- unless Rails.env.production?
213
- puts errors.full_messages if errors.respond_to? :full_messages
210
+ # puts errors.full_messages if !Rails.env.production? && errors.respond_to?(:full_messages)
211
+ head status: status && return if errors.empty?
212
+
213
+ # For retrocompatibility, I try to send back only strings, as errors
214
+ errors_response = if errors.respond_to?(:full_messages)
215
+ # Validation Errors
216
+ errors.full_messages.join(", ")
217
+ elsif errors.respond_to?(:error)
218
+ # Generic uncatched error
219
+ errors.error
220
+ elsif errors.respond_to?(:exception)
221
+ # Generic uncatchd error, if the :error property does not exist, exception will
222
+ errors.exception
223
+ elsif errors.is_a? Array
224
+ # An array of values, I like to have them merged
225
+ errors.join(", ")
226
+ else
227
+ # Uncatched Error, comething I don't know, I must return the errors as it is
228
+ errors
214
229
  end
215
- head status: status and return if errors.empty?
216
-
217
- # render json: jsonapi_format(errors).to_json, status: status
218
- render json: errors.to_json, status: status
230
+ render json: {error: errors_response}, status: status
219
231
  end
220
232
 
221
233
  def paginate(resource)
@@ -241,16 +253,11 @@ class Api::V1::BaseController < ActionController::API
241
253
  def authenticate_user!
242
254
  token, options = ActionController::HttpAuthentication::Token.token_and_options(request)
243
255
 
244
- # puts "controller: #{controller_name}\naction: #{action_name}\ntoken: #{token}\noptions: #{options.inspect}\n\n"
245
-
246
- user_email = options.blank?? nil : options[:email]
256
+ user_email = options.blank? ? nil : options[:email]
247
257
  user = user_email && User.find_by(email: user_email)
248
258
 
249
- if user && ActiveSupport::SecurityUtils.secure_compare(user.authentication_token, token)
250
- @current_user = user
251
- else
252
- return unauthenticated!
253
- end
259
+ return unauthenticated! if user.blank? || !ActiveSupport::SecurityUtils.secure_compare(user.authentication_token, token)
260
+ @current_user = user
254
261
  end
255
262
 
256
263
  # private
@@ -1,6 +1,6 @@
1
1
  class Api::V1::InfoController < Api::V1::BaseController
2
2
  # Info uses a different auth method: username and password
3
- skip_before_action :authenticate_user!, only: [:version, :translations, :schema], raise: false
3
+ skip_before_action :authenticate_user!, only: [:version], raise: false
4
4
 
5
5
  # api :GET, '/api/v1/info/version', "Just prints the APPVERSION."
6
6
  # api!
@@ -10,17 +10,17 @@ class Api::V1::InfoController < Api::V1::BaseController
10
10
  }.to_json, status: 200
11
11
  end
12
12
 
13
- # api :GET, '/api/v1/info/token', "Given auth credentials, in HTTP_BASIC form,
13
+ # api :GET, '/api/v1/info/token'
14
14
  # it returns the AUTH_TOKEN, email and id of the user which performed the authentication."
15
15
  # api!
16
- def token
17
- render json: {
18
- token: @current_user.authentication_token,
19
- email: @current_user.email
20
- }.to_json, status: 200
21
- end
16
+ # def token
17
+ # render json: {
18
+ # token: @current_user.authentication_token,
19
+ # email: @current_user.email
20
+ # }.to_json, status: 200
21
+ # end
22
22
 
23
- # api :GET, '/api/v1/info/available_roles', "Given auth credentials, in HTTP_BASIC form,
23
+ # api :GET, '/api/v1/info/available_roles'
24
24
  # it returns the roles list
25
25
  def available_roles
26
26
  render json: ROLES.to_json, status: 200
@@ -31,6 +31,7 @@ class Api::V1::InfoController < Api::V1::BaseController
31
31
  render json: I18n.t(".", locale: (params[:locale].presence || :it)).to_json, status: 200
32
32
  end
33
33
 
34
+ # GET '/api/v1/info/schema'
34
35
  def schema
35
36
  pivot = {}
36
37
  if Rails.env.development?
@@ -50,15 +51,15 @@ class Api::V1::InfoController < Api::V1::BaseController
50
51
  # private
51
52
 
52
53
  # Method overridden because the first time I have to ask for the token
53
- def authenticate_user!
54
- username, password = ActionController::HttpAuthentication::Basic.user_name_and_password(request)
55
- if username
56
- user = User.find_by(username: username)
57
- end
58
- if user && user.valid_password?(password)
59
- @current_user = user
60
- else
61
- return unauthenticated!
62
- end
63
- end
54
+ # def authenticate_user!
55
+ # username, password = ActionController::HttpAuthentication::Basic.user_name_and_password(request)
56
+ # if username
57
+ # user = User.find_by(username: username)
58
+ # end
59
+ # if user && user.valid_password?(password)
60
+ # @current_user = user
61
+ # else
62
+ # return unauthenticated!
63
+ # end
64
+ # end
64
65
  end
@@ -0,0 +1,6 @@
1
+ en:
2
+ api:
3
+ errors:
4
+ bad_credentials: Bad Credentials
5
+ unauthorized: Unauthorized Action
6
+ not_found: Resource not found
@@ -0,0 +1,6 @@
1
+ it:
2
+ api:
3
+ errors:
4
+ bad_credentials: Credenziali errate
5
+ unauthorized: Operazione non autorizzata
6
+ not_found: Risorsa non trovata
data/config/routes.rb CHANGED
@@ -10,7 +10,7 @@ Rails.application.routes.draw do
10
10
 
11
11
  namespace :info do
12
12
  get :version
13
- get :token
13
+ # get :token
14
14
  get :available_roles
15
15
  get :translations
16
16
  get :schema
@@ -1,3 +1,3 @@
1
1
  module ThecoreApi
2
- VERSION = "1.4.2".freeze
2
+ VERSION = "1.4.3".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thecore_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.2
4
+ version: 1.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabriele Tassoni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-30 00:00:00.000000000 Z
11
+ date: 2019-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thecore
@@ -96,6 +96,8 @@ files:
96
96
  - config/initializers/after_initialize_for_thecore_api.rb
97
97
  - config/initializers/cors_api_thecore.rb
98
98
  - config/initializers/wrap_parameters.rb
99
+ - config/locales/thecore_api.en.yml
100
+ - config/locales/thecore_api.it.yml
99
101
  - config/routes.rb
100
102
  - db/migrate/20181120234856_add_allowed_origins_to_settings.rb
101
103
  - lib/tasks/thecore_api_tasks.rake