motor-admin 0.1.35 → 0.1.36

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: 97e438ff28fa0c1532dc6e732da194852c6be1374040947297093abeb32d5ded
4
- data.tar.gz: 36fabae905bc320122b67e15d27bc9d34025b5b183822a2fc21420a5395a896c
3
+ metadata.gz: 8e0174dc9b889d34d1cff62947e5f330d04c37a8eea6a1036b88a5735edc3b9c
4
+ data.tar.gz: 84136e87872e4bd988055090e602e831f85516286f4dc39b9c15cd635feb5c03
5
5
  SHA512:
6
- metadata.gz: c35efea7e04d6fa2d85587508dd1828e4cbe253b8a07c5f1b28f8a7c5112c184af4910dc9b889db55930d48353c60d23fecd10718a61a4a2b1dd07acd58df2f4
7
- data.tar.gz: 103000ffc82b09b09a48416ea348ecde3537056c330fc26d41f48c2f96be84fddf7f6fd688573d526efcf2e74b64bdde2d45db19de3fc4a3f48e76debef38dc0
6
+ metadata.gz: 8d637a2d8b014e7c57c6e77b92c9c62c96ccb3a6201173e455122ab1c9f0d0cfe5070380712ce5618bf9975a225d5622336bd4e16ed1f33d689d9f340dcaf9e4
7
+ data.tar.gz: 241c173529982aa8403691eb0818f8cf5357a61ae1b7820caca288a7d91faf9f1aa00485c1a716df266777de9bac37b2da36700ed04d0463b98f05299dff8cb9
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Motor
4
+ module LoadAndAuthorizeDynamicResource
5
+ extend ActiveSupport::Concern
6
+
7
+ INSTANCE_VARIABLE_NAME = 'resource'
8
+
9
+ included do
10
+ before_action :load_and_authorize_resource
11
+ before_action :load_and_authorize_association
12
+ end
13
+
14
+ def resource_class
15
+ @resource_class ||=
16
+ Motor::BuildSchema::Utils.classify_slug(resource_name_prefix + params[:resource])
17
+ end
18
+
19
+ def resource_name_prefix
20
+ ''
21
+ end
22
+
23
+ def load_and_authorize_resource
24
+ options = {
25
+ class: resource_class,
26
+ parent: false,
27
+ instance_name: INSTANCE_VARIABLE_NAME
28
+ }
29
+
30
+ if params[:resource_id].present?
31
+ options = options.merge(
32
+ parent: true,
33
+ id_param: :resource_id
34
+ )
35
+ end
36
+
37
+ CanCan::ControllerResource.new(
38
+ self,
39
+ options
40
+ ).load_and_authorize_resource
41
+ rescue ActiveRecord::RecordNotFound
42
+ head :not_found
43
+ rescue StandardError => e
44
+ render json: { errors: [e.message] }, status: :unprocessable_entity
45
+ end
46
+
47
+ def load_and_authorize_association
48
+ return if params[:association].blank?
49
+
50
+ association = resource_class.reflections[params[:association]]
51
+
52
+ if association
53
+ CanCan::ControllerResource.new(
54
+ self,
55
+ class: association.klass,
56
+ parent: false,
57
+ through: :resource,
58
+ through_association: params[:association].to_sym,
59
+ instance_name: INSTANCE_VARIABLE_NAME
60
+ ).load_and_authorize_resource
61
+ else
62
+ render json: { message: 'Unknown association' }, status: :not_found
63
+ end
64
+ rescue ActiveRecord::RecordNotFound
65
+ head :not_found
66
+ rescue StandardError => e
67
+ render json: { errors: [e.message] }, status: :unprocessable_entity
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Motor
4
+ class AuditsController < ApiBaseController
5
+ load_and_authorize_resource :audit
6
+
7
+ def index
8
+ audits = Motor::ApiQuery.call(@audits, params)
9
+
10
+ render json: {
11
+ data: Motor::ApiQuery::BuildJson.call(audits, params),
12
+ meta: Motor::ApiQuery::BuildMeta.call(audits, params)
13
+ }
14
+ end
15
+ end
16
+ end
@@ -2,14 +2,10 @@
2
2
 
3
3
  module Motor
4
4
  class DataController < ApiBaseController
5
- include Motor::WrapIoParams
6
-
7
- INSTANCE_VARIABLE_NAME = 'resource'
8
-
9
5
  wrap_parameters :data, except: %i[include fields]
10
6
 
11
- before_action :load_and_authorize_resource
12
- before_action :load_and_authorize_association
7
+ include Motor::WrapIoParams
8
+ include Motor::LoadAndAuthorizeDynamicResource
13
9
 
14
10
  def index
15
11
  @resources = Motor::ApiQuery.call(@resources, params)
@@ -64,57 +60,6 @@ module Motor
64
60
 
65
61
  private
66
62
 
67
- def resource_class
68
- @resource_class ||= Motor::BuildSchema::Utils.classify_slug(params[:resource])
69
- end
70
-
71
- def load_and_authorize_resource
72
- options = {
73
- class: resource_class,
74
- parent: false,
75
- instance_name: INSTANCE_VARIABLE_NAME
76
- }
77
-
78
- if params[:resource_id].present?
79
- options = options.merge(
80
- parent: true,
81
- id_param: :resource_id
82
- )
83
- end
84
-
85
- CanCan::ControllerResource.new(
86
- self,
87
- options
88
- ).load_and_authorize_resource
89
- rescue ActiveRecord::RecordNotFound
90
- head :not_found
91
- rescue StandardError => e
92
- render json: { errors: [e.message] }, status: :unprocessable_entity
93
- end
94
-
95
- def load_and_authorize_association
96
- return if params[:association].blank?
97
-
98
- association = resource_class.reflections[params[:association]]
99
-
100
- if association
101
- CanCan::ControllerResource.new(
102
- self,
103
- class: association.klass,
104
- parent: false,
105
- through: :resource,
106
- through_association: params[:association].to_sym,
107
- instance_name: INSTANCE_VARIABLE_NAME
108
- ).load_and_authorize_resource
109
- else
110
- render json: { message: 'Unknown association' }, status: :not_found
111
- end
112
- rescue ActiveRecord::RecordNotFound
113
- head :not_found
114
- rescue StandardError => e
115
- render json: { errors: [e.message] }, status: :unprocessable_entity
116
- end
117
-
118
63
  def resource_params
119
64
  if params[:data].present?
120
65
  params.require(:data).except(resource_class.primary_key).permit!
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Motor
4
4
  class Alert < ::Motor::ApplicationRecord
5
+ AuditedUtils.with_audit_class(Motor::Audit) { audited }
6
+
5
7
  belongs_to :query
6
8
  belongs_to :author, polymorphic: true, optional: true
7
9
 
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Motor
4
+ class Audit < Audited::Audit
5
+ self.table_name = 'motor_audits'
6
+
7
+ serialize :audited_changes, HashSerializer
8
+ end
9
+ end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Motor
4
4
  class Config < ::Motor::ApplicationRecord
5
+ AuditedUtils.with_audit_class(Motor::Audit) { audited }
6
+
5
7
  serialize :value, HashSerializer
6
8
  end
7
9
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Motor
4
4
  class Dashboard < ::Motor::ApplicationRecord
5
+ AuditedUtils.with_audit_class(Motor::Audit) { audited }
6
+
5
7
  belongs_to :author, polymorphic: true, optional: true
6
8
 
7
9
  has_many :taggable_tags, as: :taggable
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Motor
4
4
  class Form < ::Motor::ApplicationRecord
5
+ AuditedUtils.with_audit_class(Motor::Audit) { audited }
6
+
5
7
  belongs_to :author, polymorphic: true, optional: true
6
8
 
7
9
  has_many :taggable_tags, as: :taggable
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Motor
4
4
  class Query < ::Motor::ApplicationRecord
5
+ AuditedUtils.with_audit_class(Motor::Audit) { audited }
6
+
5
7
  belongs_to :author, polymorphic: true, optional: true
6
8
 
7
9
  has_many :taggable_tags, as: :taggable
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Motor
4
4
  class Resource < ::Motor::ApplicationRecord
5
+ AuditedUtils.with_audit_class(Motor::Audit) { audited }
6
+
5
7
  serialize :preferences, HashSerializer
6
8
  end
7
9
  end
data/config/routes.rb CHANGED
@@ -15,6 +15,7 @@ Motor::Admin.routes.draw do
15
15
  resources :alerts, only: %i[index show create update destroy]
16
16
  resources :active_storage_attachments, only: %i[create], path: 'data/active_storage__attachments'
17
17
  resource :schema, only: %i[show update]
18
+ resources :audits, only: %i[index]
18
19
  resources :resources, path: '/data/:resource',
19
20
  only: %i[index show update create destroy],
20
21
  controller: 'data' do
@@ -13,9 +13,9 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
13
13
 
14
14
  t.index :updated_at
15
15
  t.index 'lower(name)',
16
- name: 'motor_queries_lower_name_unique_index',
17
- unique: true,
18
- where: 'deleted_at IS NULL'
16
+ name: 'motor_queries_lower_name_unique_index',
17
+ unique: true,
18
+ where: 'deleted_at IS NULL'
19
19
  end
20
20
 
21
21
  create_table :motor_dashboards, force: true do |t|
@@ -30,9 +30,9 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
30
30
 
31
31
  t.index :updated_at
32
32
  t.index 'lower(title)',
33
- name: 'motor_dashboards_lower_title_unique_index',
34
- unique: true,
35
- where: 'deleted_at IS NULL'
33
+ name: 'motor_dashboards_lower_title_unique_index',
34
+ unique: true,
35
+ where: 'deleted_at IS NULL'
36
36
  end
37
37
 
38
38
  create_table :motor_forms, force: true do |t|
@@ -49,9 +49,9 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
49
49
 
50
50
  t.index :updated_at
51
51
  t.index 'lower(name)',
52
- name: 'motor_forms_lower_name_unique_index',
53
- unique: true,
54
- where: 'deleted_at IS NULL'
52
+ name: 'motor_forms_lower_name_unique_index',
53
+ unique: true,
54
+ where: 'deleted_at IS NULL'
55
55
  end
56
56
 
57
57
  create_table :motor_resources, force: true do |t|
@@ -87,9 +87,9 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
87
87
 
88
88
  t.index :updated_at
89
89
  t.index 'lower(name)',
90
- name: 'motor_alerts_lower_name_unique_index',
91
- unique: true,
92
- where: 'deleted_at IS NULL'
90
+ name: 'motor_alerts_lower_name_unique_index',
91
+ unique: true,
92
+ where: 'deleted_at IS NULL'
93
93
  end
94
94
 
95
95
  create_table :motor_alert_locks, force: true do |t|
@@ -107,8 +107,8 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
107
107
  t.timestamps
108
108
 
109
109
  t.index 'lower(name)',
110
- name: 'motor_tags_lower_name_unique_index',
111
- unique: true
110
+ name: 'motor_tags_lower_name_unique_index',
111
+ unique: true
112
112
  end
113
113
 
114
114
  create_table :motor_taggable_tags, force: true do |t|
@@ -117,12 +117,36 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
117
117
  t.column :taggable_type, :string, null: false
118
118
 
119
119
  t.index %i[taggable_id taggable_type tag_id],
120
- name: 'motor_polymorphic_association_tag_index',
121
- unique: true
120
+ name: 'motor_polymorphic_association_tag_index',
121
+ unique: true
122
122
  end
123
+
124
+ create_table :motor_audits, force: true do |t|
125
+ t.column :auditable_id, :integer
126
+ t.column :auditable_type, :string
127
+ t.column :associated_id, :integer
128
+ t.column :associated_type, :string
129
+ t.column :user_id, :integer
130
+ t.column :user_type, :string
131
+ t.column :username, :string
132
+ t.column :action, :string
133
+ t.column :audited_changes, :text
134
+ t.column :version, :integer, default: 0
135
+ t.column :comment, :string
136
+ t.column :remote_address, :string
137
+ t.column :request_uuid, :string
138
+ t.column :created_at, :datetime
139
+ end
140
+
141
+ add_index :motor_audits, %i[auditable_type auditable_id version], name: 'auditable_index'
142
+ add_index :motor_audits, %i[associated_type associated_id], name: 'associated_index'
143
+ add_index :motor_audits, %i[user_id user_type], name: 'user_index'
144
+ add_index :motor_audits, :request_uuid
145
+ add_index :motor_audits, :created_at
123
146
  end
124
147
 
125
148
  def self.down
149
+ drop_table :motor_audits
126
150
  drop_table :motor_alert_locks
127
151
  drop_table :motor_alerts
128
152
  drop_table :motor_taggable_tags
data/lib/motor.rb CHANGED
@@ -6,6 +6,7 @@ require 'js_regex'
6
6
  require 'fugit'
7
7
  require 'csv'
8
8
  require 'active_record/filter'
9
+ require 'audited'
9
10
 
10
11
  module Motor
11
12
  PATH = Pathname.new(__dir__)
@@ -45,6 +46,7 @@ end
45
46
 
46
47
  require 'motor/version'
47
48
  require 'motor/admin'
49
+ require 'motor/audited_utils'
48
50
  require 'motor/assets'
49
51
  require 'motor/build_schema'
50
52
  require 'motor/api_query'
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AuditedUtils
4
+ module_function
5
+
6
+ def with_audit_class(new_class)
7
+ old_class = Audited.audit_class
8
+
9
+ Audited.audit_class = new_class
10
+
11
+ yield
12
+ ensure
13
+ Audited.audit_class = old_class
14
+ end
15
+ end
@@ -11,7 +11,7 @@ module Motor
11
11
  models.map do |model|
12
12
  build_model_schema(model)
13
13
  rescue StandardError, NotImplementedError => e
14
- Rails.logger.error(e)
14
+ Rails.logger.error(e) if model.name != 'Audited::Audit'
15
15
 
16
16
  next
17
17
  end.compact
@@ -24,6 +24,7 @@ module Motor
24
24
  models = models.reject(&:abstract_class)
25
25
 
26
26
  models -= Motor::ApplicationRecord.descendants
27
+ models -= [Motor::Audit]
27
28
  models -= [ActiveRecord::SchemaMigration] if defined?(ActiveRecord::SchemaMigration)
28
29
  models -= [ActiveStorage::Blob] if defined?(ActiveStorage::Blob)
29
30
  models -= [ActiveStorage::VariantRecord] if defined?(ActiveStorage::VariantRecord)
data/lib/motor/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Motor
4
- VERSION = '0.1.35'
4
+ VERSION = '0.1.36'
5
5
  end
@@ -5,9 +5,9 @@
5
5
  "fonts/ionicons.ttf?v=3.0.0-alpha.3": "fonts/ionicons.ttf",
6
6
  "fonts/ionicons.woff2?v=3.0.0-alpha.3": "fonts/ionicons.woff2",
7
7
  "fonts/ionicons.woff?v=3.0.0-alpha.3": "fonts/ionicons.woff",
8
- "main-03c3b1d3390877206e02.css.gz": "main-03c3b1d3390877206e02.css.gz",
9
- "main-03c3b1d3390877206e02.js.LICENSE.txt": "main-03c3b1d3390877206e02.js.LICENSE.txt",
10
- "main-03c3b1d3390877206e02.js.gz": "main-03c3b1d3390877206e02.js.gz",
11
- "main.css": "main-03c3b1d3390877206e02.css",
12
- "main.js": "main-03c3b1d3390877206e02.js"
8
+ "main-358ea31cd7020f915067.css.gz": "main-358ea31cd7020f915067.css.gz",
9
+ "main-358ea31cd7020f915067.js.LICENSE.txt": "main-358ea31cd7020f915067.js.LICENSE.txt",
10
+ "main-358ea31cd7020f915067.js.gz": "main-358ea31cd7020f915067.js.gz",
11
+ "main.css": "main-358ea31cd7020f915067.css",
12
+ "main.js": "main-358ea31cd7020f915067.js"
13
13
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motor-admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.35
4
+ version: 0.1.36
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pete Matsyburka
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-11 00:00:00.000000000 Z
11
+ date: 2021-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord-filter
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.6.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: audited
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.9'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '4.9'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: cancancan
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -132,12 +146,14 @@ files:
132
146
  - LICENSE
133
147
  - README.md
134
148
  - Rakefile
149
+ - app/controllers/concerns/motor/load_and_authorize_dynamic_resource.rb
135
150
  - app/controllers/concerns/motor/wrap_io_params.rb
136
151
  - app/controllers/motor/active_storage_attachments_controller.rb
137
152
  - app/controllers/motor/alerts_controller.rb
138
153
  - app/controllers/motor/api_base_controller.rb
139
154
  - app/controllers/motor/application_controller.rb
140
155
  - app/controllers/motor/assets_controller.rb
156
+ - app/controllers/motor/audits_controller.rb
141
157
  - app/controllers/motor/configs_controller.rb
142
158
  - app/controllers/motor/dashboards_controller.rb
143
159
  - app/controllers/motor/data_controller.rb
@@ -157,6 +173,7 @@ files:
157
173
  - app/models/motor/alert.rb
158
174
  - app/models/motor/alert_lock.rb
159
175
  - app/models/motor/application_record.rb
176
+ - app/models/motor/audit.rb
160
177
  - app/models/motor/config.rb
161
178
  - app/models/motor/dashboard.rb
162
179
  - app/models/motor/form.rb
@@ -192,6 +209,7 @@ files:
192
209
  - lib/motor/api_query/search.rb
193
210
  - lib/motor/api_query/sort.rb
194
211
  - lib/motor/assets.rb
212
+ - lib/motor/audited_utils.rb
195
213
  - lib/motor/build_schema.rb
196
214
  - lib/motor/build_schema/active_storage_attachment_schema.rb
197
215
  - lib/motor/build_schema/find_display_column.rb
@@ -214,8 +232,8 @@ files:
214
232
  - lib/motor/ui_configs.rb
215
233
  - lib/motor/version.rb
216
234
  - ui/dist/fonts/ionicons.woff2
217
- - ui/dist/main-03c3b1d3390877206e02.css.gz
218
- - ui/dist/main-03c3b1d3390877206e02.js.gz
235
+ - ui/dist/main-358ea31cd7020f915067.css.gz
236
+ - ui/dist/main-358ea31cd7020f915067.js.gz
219
237
  - ui/dist/manifest.json
220
238
  homepage:
221
239
  licenses: