tina4ruby 3.13.62 → 3.13.63

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: 2654a6c8f7c322aeb7b6719ff4e908840e4dec23afa49dc02e165a0b0c74b0c7
4
- data.tar.gz: a5b0f4e3813c0597f7d6734ba5472a4641f70af228c8ad9513166519743f0e0b
3
+ metadata.gz: 51cd83415eaad0fc64019fcbab89e92fb0cfb90cd9a3e1a3db6122499c14c83f
4
+ data.tar.gz: 9f1283a11d1f433d3ca39ae961db99bc73aa0e1f462336508c696ebbceaf9642
5
5
  SHA512:
6
- metadata.gz: 5fc83c37a2afdb997a9faf495d1fb6547b287b968ae40a93c94c404142f4e783e2cb569796ee2072a09e11d356ec53336b1d5858ed8d2e029a7562a8d8fec255
7
- data.tar.gz: bd2a127e45f88513764af879ad80a5abe166001661cb0809b9af5d00e9ce9d950513a8afaef85ddf562d2d0a48945e068e4f236ac3a494893ab4cdedbc705c0c
6
+ metadata.gz: 59ceaebe4dea54ec1b9e4894efee36cb1d98af2e9bdfc919033a055f5824d12f37f523177003b4a0f2497d0ca0f0a4c3086628f8ae1e29e8035beda64a7ea4b5
7
+ data.tar.gz: 6aa2471f6a38fe85d13e8832f68c23fd093ec0bbf9837f6ff6da220880428af9851c044cbf4d89f9cbd4ae64c1cc1c4f73e9373d3037902731018227fb6d0bbb
@@ -9,15 +9,32 @@ module Tina4
9
9
  @models ||= []
10
10
  end
11
11
 
12
- # Register a model for auto-CRUD
13
- def register(model_class)
12
+ # Per-model public-writes flag (model_class => Boolean).
13
+ # Default secure; only set true when a model is registered `public: true`.
14
+ # Mirrors tina4-php's `$this->public` map. Write routes stay gated unless
15
+ # a model is explicitly opted out.
16
+ def public_flags
17
+ @public_flags ||= {}
18
+ end
19
+
20
+ # Register a model for auto-CRUD.
21
+ #
22
+ # @param model_class [Class] the ORM subclass to expose
23
+ # @param public [Boolean] when true, the generated write routes
24
+ # (POST/PUT/DELETE) opt OUT of the framework's secure-by-default write
25
+ # gate — they are marked `.no_auth`. Default false keeps writes gated
26
+ # (a valid bearer token is required), matching the router's rule that
27
+ # POST/PUT/PATCH/DELETE require auth unless explicitly opened. Parity
28
+ # with tina4-python / tina4-php.
29
+ def register(model_class, public: false)
14
30
  models << model_class unless models.include?(model_class)
31
+ public_flags[model_class] = public
15
32
  end
16
33
 
17
34
  # Generate REST endpoints for all registered models
18
35
  def generate_routes(prefix: "/api")
19
36
  models.each do |model_class|
20
- generate_routes_for(model_class, prefix: prefix)
37
+ generate_routes_for(model_class, prefix: prefix, public: public_flags[model_class])
21
38
  end
22
39
  end
23
40
 
@@ -45,13 +62,25 @@ module Tina4
45
62
  example
46
63
  end
47
64
 
48
- # Generate REST endpoints for a single model class
49
- def generate_routes_for(model_class, prefix: "/api")
65
+ # Generate REST endpoints for a single model class.
66
+ #
67
+ # @param model_class [Class] the ORM subclass to expose
68
+ # @param prefix [String] URL prefix for the generated routes
69
+ # @param public [Boolean, nil] when true, the write routes
70
+ # (POST/PUT/DELETE) opt out of the secure-by-default gate via
71
+ # `.no_auth`. When nil (the default), the flag stored at register()
72
+ # time is used, falling back to false (secure). The read routes (GET)
73
+ # are never gated regardless.
74
+ def generate_routes_for(model_class, prefix: "/api", public: nil)
50
75
  table = model_class.table_name
51
76
  pk = model_class.primary_key_field || :id
52
77
  pretty_name = table.to_s.split("_").map(&:capitalize).join(" ")
53
78
  example_body = build_example(model_class)
54
79
 
80
+ # Explicit arg wins; otherwise fall back to the flag recorded by
81
+ # register(), otherwise secure-by-default.
82
+ is_public = public.nil? ? (public_flags[model_class] || false) : public
83
+
55
84
  # GET /api/{table} -- list all with pagination, filtering, sorting
56
85
  Tina4::Router.add("GET", "#{prefix}/#{table}", proc { |req, res|
57
86
  begin
@@ -109,7 +138,7 @@ module Tina4
109
138
  }, swagger_meta: { summary: "Get #{pretty_name} by ID", tags: [table.to_s] })
110
139
 
111
140
  # POST /api/{table} -- create record
112
- Tina4::Router.add("POST", "#{prefix}/#{table}", proc { |req, res|
141
+ post_route = Tina4::Router.add("POST", "#{prefix}/#{table}", proc { |req, res|
113
142
  begin
114
143
  attributes = req.body_parsed
115
144
  record = model_class.create(attributes)
@@ -136,8 +165,11 @@ module Tina4
136
165
  }
137
166
  })
138
167
 
168
+ # Secure-by-default: only opt out of the write gate when public: true.
169
+ post_route.no_auth if is_public
170
+
139
171
  # PUT /api/{table}/{id} -- update record
140
- Tina4::Router.add("PUT", "#{prefix}/#{table}/{id}", proc { |req, res|
172
+ put_route = Tina4::Router.add("PUT", "#{prefix}/#{table}/{id}", proc { |req, res|
141
173
  begin
142
174
  id = req.params["id"]
143
175
  record = model_class.find_by_id(id.to_i)
@@ -174,8 +206,11 @@ module Tina4
174
206
  }
175
207
  })
176
208
 
209
+ # Secure-by-default: only opt out of the write gate when public: true.
210
+ put_route.no_auth if is_public
211
+
177
212
  # DELETE /api/{table}/{id} -- delete record
178
- Tina4::Router.add("DELETE", "#{prefix}/#{table}/{id}", proc { |req, res|
213
+ delete_route = Tina4::Router.add("DELETE", "#{prefix}/#{table}/{id}", proc { |req, res|
179
214
  begin
180
215
  id = req.params["id"]
181
216
  record = model_class.find_by_id(id.to_i)
@@ -192,14 +227,20 @@ module Tina4
192
227
  res.json({ error: e.message }, status: 500)
193
228
  end
194
229
  }, swagger_meta: { summary: "Delete #{pretty_name}", tags: [table.to_s] })
230
+
231
+ # Secure-by-default: only opt out of the write gate when public: true.
232
+ delete_route.no_auth if is_public
195
233
  end
196
234
 
197
235
  # Discover ORM model classes from a directory and register them.
198
236
  #
199
237
  # @param models_dir [String] directory to scan (default "src/orm")
200
238
  # @param prefix [String] URL prefix for generated routes (default "/api")
239
+ # @param public [Boolean] when true, opt discovered models' write routes
240
+ # out of the secure-by-default gate (see .register). Default false keeps
241
+ # writes gated. Parity with tina4-python / tina4-php.
201
242
  # @return [Array<String>] list of discovered model class names
202
- def discover(models_dir = "src/orm", prefix: "/api")
243
+ def discover(models_dir = "src/orm", prefix: "/api", public: false)
203
244
  discovered = []
204
245
  return discovered unless Dir.exist?(models_dir)
205
246
 
@@ -210,7 +251,7 @@ module Tina4
210
251
  # Find all ORM subclasses that have a table_name
211
252
  ObjectSpace.each_object(Class).select { |c| c < Tina4::ORM rescue false }.each do |klass|
212
253
  next unless klass.respond_to?(:table_name) && klass.table_name
213
- register(klass)
254
+ register(klass, public: public)
214
255
  discovered << klass.name
215
256
  end
216
257
 
@@ -220,6 +261,7 @@ module Tina4
220
261
 
221
262
  def clear!
222
263
  @models = []
264
+ @public_flags = {}
223
265
  end
224
266
 
225
267
  # Alias for parity with other frameworks
data/lib/tina4/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tina4
4
- VERSION = "3.13.62"
4
+ VERSION = "3.13.63"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tina4ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.13.62
4
+ version: 3.13.63
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tina4 Team