model_driven_api 3.1.7 → 3.1.9

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: 1272f499542ca137fd53edb4e8e0221021c9640a8d0f964fc41546c6d55e3873
4
- data.tar.gz: 23c1b8dafdcf82ffdfcc68113568ee07e9bd9ee10efaaeb860be8459e09a1c2e
3
+ metadata.gz: 94b18a1b177632591c520596c5b8443da17b84937c934b450550512355d4690d
4
+ data.tar.gz: 8992f753df4957e584a303989130f48ef63346f9adff290f72140bc2f7df14f7
5
5
  SHA512:
6
- metadata.gz: 53941a7154e66342de797d2350fffe085f74cc6ddafc75c4d15231e14d1628b1d03c6891ee74674e0a47f634550cfc4c01bb335f2b58b5b592da5b20c4b72559
7
- data.tar.gz: 22289e5e28cdd414390d2019b9f48526d606eacbdc026c259f3c8444fcf039b712e5099062f0b811970ce3ba00d3803870c97541faa6b94e2c5c2662ee89e856
6
+ metadata.gz: be09d8af6479897b60e760e1d8a1096804acca2a881a9dba302af39a701eeeba3e801ca09bd25caadcdc3a4ae20d8ea0280e9e70458331ea2a53d6a7bbba55b0
7
+ data.tar.gz: a49c63942e572826abe3e6176bca618589993da59957d012a34db8b49acd4550102b0fb8987a8a602faf20be56363ace53c53fe1496feb97316cd7796edf736d
@@ -121,36 +121,54 @@ class Api::V2::ApplicationController < ActionController::API
121
121
 
122
122
  private
123
123
 
124
+ ## CUSTOM ACTION
125
+ # [GET|PUT|POST|DELETE] :controller?do=:custom_action
126
+ # or
127
+ # [GET|PUT|POST|DELETE] :controller/:id?do=:
128
+ # or
129
+ # [GET|PUT|POST|DELETE] :controller?do=:custom_action-token
130
+ # or
131
+ # [GET|PUT|POST|DELETE] :controller/:id?do=:custom_action-token
132
+ # or
133
+ # [GET|PUT|POST|DELETE] :controller/custom_action/:custom_action
134
+ # or
135
+ # [GET|PUT|POST|DELETE] :controller/custom_action/:custom_action/:id
124
136
  def check_for_custom_action
125
- ## CUSTOM ACTION
126
- # [GET|PUT|POST|DELETE] :controller?do=:custom_action
127
- # or
128
- # [GET|PUT|POST|DELETE] :controller/:id?do=:custom_action
129
- unless params[:do].blank?
130
- # Poor man's solution to avoid the possibility to
131
- # call an unwanted method in the AR Model.
132
- custom_action, token = params[:do].split("-")
133
-
134
- params[:request_url] = request.url
135
- params[:remote_ip] = request.remote_ip
136
- params[:token] = token.presence || bearer_token
137
- # The endpoint can be expressed in two wayy:
138
- # 1. As a method in the model, with suffix custom_action_<custom_action>
139
- # 2. As a module instance method in the model, like Track::Endpoints.inventory
140
- if defined?("Endpoints::#{@model}.#{custom_action}")
141
- # Custom endpoint exists and can be called in the sub-modules form
142
- body, status = "Endpoints::#{@model}".constantize.send(custom_action, params)
143
- elsif @model.respond_to?("custom_action_#{custom_action}")
144
- body, status = @model.send("custom_action_#{custom_action}", params)
145
- else
146
- # Custom endpoint does not exist or cannot be called
147
- raise NoMethodError
148
- end
149
-
150
- return true, body.to_json(json_attrs), status
137
+
138
+ custom_action, token = if !params[:do].blank?
139
+ # This also responds to custom actions which have the bearer token in the custom action name. A workaround to remove for some IoT devices
140
+ # Which don't support token in header or in querystring
141
+ # This is for backward compatibility and in future it can ben removed
142
+ params[:do].split("-")
143
+ elsif request.url.include? "/custom_action/"
144
+ [params[:action_name], nil]
145
+ else
146
+ # Not a custom action call
147
+ false
151
148
  end
152
- # if it's here there is no custom action in the request querystring
153
- return false
149
+ return false unless custom_action
150
+ # Poor man's solution to avoid the possibility to
151
+ # call an unwanted method in the AR Model.
152
+
153
+ # Adding some useful information to the params hash
154
+ params[:request_url] = request.url
155
+ params[:remote_ip] = request.remote_ip
156
+ params[:request_verb] = request.request_method
157
+ params[:token] = token.presence || bearer_token
158
+ # The endpoint can be expressed in two ways:
159
+ # 1. As a method in the model, with suffix custom_action_<custom_action>
160
+ # 2. As a module instance method in the model, like Track::Endpoints.inventory
161
+ if defined?("Endpoints::#{@model}.#{custom_action}")
162
+ # Custom endpoint exists and can be called in the sub-modules form
163
+ body, status = "Endpoints::#{@model}".constantize.send(custom_action, params)
164
+ elsif @model.respond_to?("custom_action_#{custom_action}")
165
+ body, status = @model.send("custom_action_#{custom_action}", params)
166
+ else
167
+ # Custom endpoint does not exist or cannot be called
168
+ raise NoMethodError
169
+ end
170
+
171
+ return true, body.to_json(json_attrs), status
154
172
  end
155
173
 
156
174
  def bearer_token
@@ -209,9 +227,9 @@ class Api::V2::ApplicationController < ActionController::API
209
227
  @model = (params[:ctrl].classify.constantize rescue params[:path].split("/").first.classify.constantize rescue controller_path.classify.constantize rescue controller_name.classify.constantize rescue nil)
210
228
  # Getting the body of the request if it exists, it's ok the singular or
211
229
  # plural form, this helps with automatic tests with Insomnia.
212
- @body = params[@model.model_name.singular].presence || params[@model.model_name.route_key]
230
+ @body = (params[@model.model_name.singular].presence || params[@model.model_name.route_key]) rescue params
213
231
  # Only ActiveRecords can have this model caputed
214
- return not_found! if (!@model.new.is_a? ActiveRecord::Base rescue false)
232
+ return not_found! if (@model != TestApi && !@model.new.is_a?(ActiveRecord::Base) rescue false)
215
233
  end
216
234
 
217
235
  def check_authorization(cmd)
@@ -516,10 +516,12 @@ class Api::V2::InfoController < Api::V2::ApplicationController
516
516
  }
517
517
  # Non CRUD or Search, but custom, usually bulk operations endpoints
518
518
  custom_actions = d.methods(false).select do |m| m.to_s.starts_with?("custom_action_") end
519
+ # Add also custom actions created using th enew Endpoints Interface
520
+ custom_actions += "Endpoints::#{d.model_name.name}".constantize.methods(false) rescue []
519
521
  custom_actions.each do |action|
520
522
  custom_action_name = action.to_s.gsub("custom_action_", "")
521
523
  pivot["/#{model}/custom_action/#{custom_action_name}"] = {
522
- "post": {
524
+ "get": {
523
525
  "summary": "Custom Action #{custom_action_name.titleize}",
524
526
  "description": "This is just an example of a custom action, they can accept a wide range of payloads and response with a wide range of responses, also all verbs are valid. Please refer to the documentation for more information.",
525
527
  "tags": [model.classify],
@@ -0,0 +1,23 @@
1
+ module Endpoints::TestApi
2
+ def self.test params
3
+ # Define an explain var to be used to validate and document the action behavior when using ?explain=true in query string
4
+ explain = {
5
+ verbs: ["GET"],
6
+ body: {},
7
+ query: {},
8
+ responses: {
9
+ 200 => {
10
+ message: :string,
11
+ params: {}
12
+ },
13
+ 501 => {
14
+ error: :string
15
+ }
16
+ }
17
+ }
18
+
19
+ return explain, 200 if params[:explain] == "true"
20
+ return { error: "This method responds only to #{explain[:verbs].join(", ")} requests" }, 501 if explain[:verbs].exclude? params[:request_verb]
21
+ return { message: "Hello World From Test API Custom Action called test", params: params }, 200
22
+ end
23
+ end
@@ -0,0 +1,6 @@
1
+ class TestApi
2
+ # Initialize the class with the request params
3
+ def initialize params
4
+ @params = params
5
+ end
6
+ end
data/config/routes.rb CHANGED
@@ -21,19 +21,30 @@ Rails.application.routes.draw do
21
21
  post "authenticate" => "authentication#authenticate"
22
22
  post ":ctrl/search" => 'application#index'
23
23
 
24
+ # Add a route with placeholders for custom actions, the custom actions routes have a form like: :ctrl/custom_action/:action_name or :ctrl/custom_action/:action_name/:id
25
+ # Can have all the verbs, but the most common are: get, post, put, delete
26
+ get ":ctrl/custom_action/:action_name", to: 'application#index'
27
+ get ":ctrl/custom_action/:action_name/:id", to: 'application#show'
28
+ post ":ctrl/custom_action/:action_name", to: 'application#create'
29
+ put ":ctrl/custom_action/:action_name/:id", to: 'application#update'
30
+ patch ":ctrl/custom_action/:action_name/:id", to: 'application#update'
31
+ delete ":ctrl/custom_action/:action_name/:id", to: 'application#destroy'
24
32
  # Catchall routes
25
- # # CRUD Show
26
- get '*path/:id', to: 'application#show'
27
- # # CRUD Index
28
- get '*path', to: 'application#index'
29
- # # CRUD Create
30
- post '*path', to: 'application#create'
33
+ # # # CRUD Show
34
+ # get '*path/:id', to: 'application#show'
35
+ # # # CRUD Index
36
+ # get '*path', to: 'application#index'
37
+ # # # CRUD Create
38
+ # post '*path', to: 'application#create'
31
39
  # # CRUD Update
32
40
  put '*path/:id/multi', to: 'application#update_multi'
33
- put '*path/:id', to: 'application#update'
41
+ patch '*path/:id/multi', to: 'application#update_multi'
42
+ # put '*path/:id', to: 'application#update'
43
+ # patch '*path/:id', to: 'application#patch'
44
+
34
45
  # # CRUD Delete
35
46
  delete '*path/:id/multi', to: 'application#destroy_multi'
36
- delete '*path/:id', to: 'application#destroy'
47
+ # delete '*path/:id', to: 'application#destroy'
37
48
  end
38
49
  end
39
50
  end
@@ -1,3 +1,3 @@
1
1
  module ModelDrivenApi
2
- VERSION = "3.1.7".freeze
2
+ VERSION = "3.1.9".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: model_driven_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.7
4
+ version: 3.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabriele Tassoni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-05 00:00:00.000000000 Z
11
+ date: 2024-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thecore_backend_commons
@@ -125,6 +125,8 @@ files:
125
125
  - app/controllers/api/v2/authentication_controller.rb
126
126
  - app/controllers/api/v2/info_controller.rb
127
127
  - app/controllers/api/v2/users_controller.rb
128
+ - app/models/concerns/endpoints/test_api.rb
129
+ - app/models/test_api.rb
128
130
  - app/models/used_token.rb
129
131
  - config/initializers/after_initialize_for_model_driven_api.rb
130
132
  - config/initializers/cors_api_thecore.rb