easy-admin-rails 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +8 -0
- data/app/assets/builds/easy_admin.base.js +43505 -0
- data/app/assets/builds/easy_admin.base.js.map +7 -0
- data/app/assets/builds/easy_admin.css +6141 -0
- data/app/assets/config/easy_admin_manifest.js +1 -0
- data/app/assets/images/jsoneditor-icons.svg +749 -0
- data/app/assets/stylesheets/easy_admin/application.tailwind.css +390 -0
- data/app/components/easy_admin/base_component.rb +35 -0
- data/app/components/easy_admin/batch_action_bar_component.rb +125 -0
- data/app/components/easy_admin/batch_action_form_component.rb +124 -0
- data/app/components/easy_admin/combined_filters_component.rb +232 -0
- data/app/components/easy_admin/confirmation_modal_component.rb +61 -0
- data/app/components/easy_admin/context_menu_component.rb +161 -0
- data/app/components/easy_admin/dashboards/base_card_component.rb +152 -0
- data/app/components/easy_admin/dashboards/card_error_component.rb +23 -0
- data/app/components/easy_admin/dashboards/card_factory.rb +90 -0
- data/app/components/easy_admin/dashboards/card_stream_component.rb +22 -0
- data/app/components/easy_admin/dashboards/cards/base_card_component.rb +54 -0
- data/app/components/easy_admin/dashboards/cards/chart_card_component.rb +175 -0
- data/app/components/easy_admin/dashboards/cards/custom_card_component.rb +50 -0
- data/app/components/easy_admin/dashboards/cards/metric_card_component.rb +164 -0
- data/app/components/easy_admin/dashboards/cards/table_card_component.rb +148 -0
- data/app/components/easy_admin/dashboards/chart_card_component.rb +44 -0
- data/app/components/easy_admin/dashboards/metric_card_component.rb +56 -0
- data/app/components/easy_admin/dashboards/refresh_stream_component.rb +279 -0
- data/app/components/easy_admin/dashboards/show_component.rb +163 -0
- data/app/components/easy_admin/dashboards/table_card_component.rb +52 -0
- data/app/components/easy_admin/date_picker_component.rb +188 -0
- data/app/components/easy_admin/fields/base_component.rb +101 -0
- data/app/components/easy_admin/fields/belongs_to_edit_modal_component.rb +117 -0
- data/app/components/easy_admin/fields/form/belongs_to_component.rb +82 -0
- data/app/components/easy_admin/fields/form/boolean_component.rb +100 -0
- data/app/components/easy_admin/fields/form/date_component.rb +55 -0
- data/app/components/easy_admin/fields/form/datetime_component.rb +55 -0
- data/app/components/easy_admin/fields/form/email_component.rb +55 -0
- data/app/components/easy_admin/fields/form/file_component.rb +190 -0
- data/app/components/easy_admin/fields/form/has_many_component.rb +416 -0
- data/app/components/easy_admin/fields/form/json_component.rb +81 -0
- data/app/components/easy_admin/fields/form/number_component.rb +55 -0
- data/app/components/easy_admin/fields/form/select_component.rb +326 -0
- data/app/components/easy_admin/fields/form/text_component.rb +55 -0
- data/app/components/easy_admin/fields/form/textarea_component.rb +54 -0
- data/app/components/easy_admin/fields/index/belongs_to_component.rb +93 -0
- data/app/components/easy_admin/fields/index/boolean_component.rb +29 -0
- data/app/components/easy_admin/fields/index/date_component.rb +13 -0
- data/app/components/easy_admin/fields/index/datetime_component.rb +13 -0
- data/app/components/easy_admin/fields/index/email_component.rb +24 -0
- data/app/components/easy_admin/fields/index/filters/base_component.rb +48 -0
- data/app/components/easy_admin/fields/index/filters/boolean_component.rb +96 -0
- data/app/components/easy_admin/fields/index/filters/date_component.rb +182 -0
- data/app/components/easy_admin/fields/index/filters/number_component.rb +30 -0
- data/app/components/easy_admin/fields/index/filters/select_component.rb +101 -0
- data/app/components/easy_admin/fields/index/filters/string_component.rb +32 -0
- data/app/components/easy_admin/fields/index/json_component.rb +23 -0
- data/app/components/easy_admin/fields/index/number_component.rb +20 -0
- data/app/components/easy_admin/fields/index/select_component.rb +25 -0
- data/app/components/easy_admin/fields/index/text_component.rb +20 -0
- data/app/components/easy_admin/fields/inline_edit_modal_component.rb +135 -0
- data/app/components/easy_admin/fields/inline_edit_trigger_component.rb +144 -0
- data/app/components/easy_admin/fields/show/belongs_to_component.rb +93 -0
- data/app/components/easy_admin/fields/show/boolean_component.rb +21 -0
- data/app/components/easy_admin/fields/show/date_component.rb +13 -0
- data/app/components/easy_admin/fields/show/datetime_component.rb +13 -0
- data/app/components/easy_admin/fields/show/email_component.rb +19 -0
- data/app/components/easy_admin/fields/show/file_component.rb +304 -0
- data/app/components/easy_admin/fields/show/has_many_component.rb +192 -0
- data/app/components/easy_admin/fields/show/json_component.rb +45 -0
- data/app/components/easy_admin/fields/show/number_component.rb +20 -0
- data/app/components/easy_admin/fields/show/select_component.rb +25 -0
- data/app/components/easy_admin/fields/show/text_component.rb +17 -0
- data/app/components/easy_admin/fields/show/textarea_component.rb +26 -0
- data/app/components/easy_admin/filters_component.rb +120 -0
- data/app/components/easy_admin/form_tabs_component.rb +166 -0
- data/app/components/easy_admin/infinite_scroll_component.rb +82 -0
- data/app/components/easy_admin/lazy_chart_card_component.rb +128 -0
- data/app/components/easy_admin/lazy_metric_card_component.rb +76 -0
- data/app/components/easy_admin/modal_frame_component.rb +26 -0
- data/app/components/easy_admin/navbar_component.rb +226 -0
- data/app/components/easy_admin/notification_component.rb +83 -0
- data/app/components/easy_admin/pagination_component.rb +188 -0
- data/app/components/easy_admin/quick_filters_component.rb +65 -0
- data/app/components/easy_admin/resource_pagination_component.rb +14 -0
- data/app/components/easy_admin/resources/index_component.rb +211 -0
- data/app/components/easy_admin/resources/index_frame_component.rb +88 -0
- data/app/components/easy_admin/resources/show_page_actions_component.rb +324 -0
- data/app/components/easy_admin/resources/table_cell_component.rb +145 -0
- data/app/components/easy_admin/resources/table_component.rb +206 -0
- data/app/components/easy_admin/resources/table_row_component.rb +160 -0
- data/app/components/easy_admin/row_action_form_component.rb +127 -0
- data/app/components/easy_admin/scopes_component.rb +224 -0
- data/app/components/easy_admin/settings_sidebar_component.rb +140 -0
- data/app/components/easy_admin/show_layout_component.rb +600 -0
- data/app/components/easy_admin/sidebar_component.rb +174 -0
- data/app/components/easy_admin/turbo/response_component.rb +40 -0
- data/app/components/easy_admin/turbo/stream_component.rb +28 -0
- data/app/controllers/easy_admin/application_controller.rb +66 -0
- data/app/controllers/easy_admin/batch_actions_controller.rb +166 -0
- data/app/controllers/easy_admin/confirmation_modal_controller.rb +20 -0
- data/app/controllers/easy_admin/dashboard_controller.rb +6 -0
- data/app/controllers/easy_admin/dashboards_controller.rb +123 -0
- data/app/controllers/easy_admin/passwords_controller.rb +15 -0
- data/app/controllers/easy_admin/registrations_controller.rb +52 -0
- data/app/controllers/easy_admin/resources_controller.rb +907 -0
- data/app/controllers/easy_admin/row_actions_controller.rb +216 -0
- data/app/controllers/easy_admin/sessions_controller.rb +32 -0
- data/app/controllers/easy_admin/settings_controller.rb +94 -0
- data/app/helpers/easy_admin/application_helper.rb +4 -0
- data/app/helpers/easy_admin/dashboards_helper.rb +121 -0
- data/app/helpers/easy_admin/fields_helper.rb +27 -0
- data/app/helpers/easy_admin/pagy_helper.rb +30 -0
- data/app/helpers/easy_admin/resources_helper.rb +39 -0
- data/app/javascript/easy_admin/application.js +12 -0
- data/app/javascript/easy_admin/controllers/batch_modal_controller.js +66 -0
- data/app/javascript/easy_admin/controllers/batch_selection_controller.js +223 -0
- data/app/javascript/easy_admin/controllers/chart_controller.js +216 -0
- data/app/javascript/easy_admin/controllers/collapsible_filters_controller.js +118 -0
- data/app/javascript/easy_admin/controllers/confirmation_modal_controller.js +64 -0
- data/app/javascript/easy_admin/controllers/context_menu_controller.js +227 -0
- data/app/javascript/easy_admin/controllers/date_picker_controller.js +309 -0
- data/app/javascript/easy_admin/controllers/dropdown_controller.js +63 -0
- data/app/javascript/easy_admin/controllers/event_emitter_controller.js +19 -0
- data/app/javascript/easy_admin/controllers/file_controller.js +121 -0
- data/app/javascript/easy_admin/controllers/form_tabs_controller.js +100 -0
- data/app/javascript/easy_admin/controllers/has_many_search_controller.js +76 -0
- data/app/javascript/easy_admin/controllers/infinite_scroll_controller.js +174 -0
- data/app/javascript/easy_admin/controllers/ios_alert_controller.js +195 -0
- data/app/javascript/easy_admin/controllers/jsoneditor_controller.js +88 -0
- data/app/javascript/easy_admin/controllers/modal_controller.js +75 -0
- data/app/javascript/easy_admin/controllers/navbar_scroll_controller.js +76 -0
- data/app/javascript/easy_admin/controllers/notification_controller.js +48 -0
- data/app/javascript/easy_admin/controllers/row_action_controller.js +124 -0
- data/app/javascript/easy_admin/controllers/row_modal_controller.js +59 -0
- data/app/javascript/easy_admin/controllers/select_field_controller.js +618 -0
- data/app/javascript/easy_admin/controllers/settings_button_controller.js +8 -0
- data/app/javascript/easy_admin/controllers/settings_sidebar_controller.js +186 -0
- data/app/javascript/easy_admin/controllers/sidebar_controller.js +102 -0
- data/app/javascript/easy_admin/controllers/sidebar_mobile_controller.js +23 -0
- data/app/javascript/easy_admin/controllers/sidebar_nav_controller.js +96 -0
- data/app/javascript/easy_admin/controllers/table_controller.js +28 -0
- data/app/javascript/easy_admin/controllers/table_row_controller.js +16 -0
- data/app/javascript/easy_admin/controllers/toggle_switch_controller.js +22 -0
- data/app/javascript/easy_admin/controllers/turbo_stream_redirect.js +9 -0
- data/app/javascript/easy_admin/controllers.js +54 -0
- data/app/javascript/easy_admin.base.js +4 -0
- data/app/models/easy_admin/admin_user.rb +53 -0
- data/app/models/easy_admin/application_record.rb +5 -0
- data/app/views/easy_admin/dashboard/index.html.erb +3 -0
- data/app/views/easy_admin/dashboards/show.html.erb +7 -0
- data/app/views/easy_admin/passwords/edit.html.erb +42 -0
- data/app/views/easy_admin/passwords/new.html.erb +41 -0
- data/app/views/easy_admin/registrations/new.html.erb +65 -0
- data/app/views/easy_admin/resources/_redirect.turbo_stream.erb +3 -0
- data/app/views/easy_admin/resources/_table_rows.html.erb +46 -0
- data/app/views/easy_admin/resources/edit.html.erb +151 -0
- data/app/views/easy_admin/resources/index.html.erb +12 -0
- data/app/views/easy_admin/resources/index.turbo_stream.erb +139 -0
- data/app/views/easy_admin/resources/index_frame.html.erb +142 -0
- data/app/views/easy_admin/resources/new.html.erb +100 -0
- data/app/views/easy_admin/resources/show.html.erb +31 -0
- data/app/views/easy_admin/sessions/new.html.erb +55 -0
- data/app/views/easy_admin/settings/_form.html.erb +51 -0
- data/app/views/easy_admin/settings/index.html.erb +53 -0
- data/app/views/layouts/easy_admin/application.html.erb +48 -0
- data/app/views/layouts/easy_admin/auth.html.erb +34 -0
- data/config/initializers/easy_admin_card_factory.rb +27 -0
- data/config/initializers/pagy.rb +15 -0
- data/config/initializers/rack_mini_profiler.rb +67 -0
- data/config/routes.rb +70 -0
- data/db/migrate/20250101000001_create_easy_admin_admin_users.rb +45 -0
- data/lib/easy-admin.rb +32 -0
- data/lib/easy_admin/action.rb +159 -0
- data/lib/easy_admin/batch_action.rb +134 -0
- data/lib/easy_admin/configuration.rb +75 -0
- data/lib/easy_admin/dashboard.rb +110 -0
- data/lib/easy_admin/dashboard_registry.rb +30 -0
- data/lib/easy_admin/delete_action.rb +22 -0
- data/lib/easy_admin/engine.rb +54 -0
- data/lib/easy_admin/field.rb +118 -0
- data/lib/easy_admin/resource.rb +806 -0
- data/lib/easy_admin/resource_registry.rb +22 -0
- data/lib/easy_admin/types/json_type.rb +25 -0
- data/lib/easy_admin/version.rb +3 -0
- data/lib/generators/easy_admin/auth_generator.rb +69 -0
- data/lib/generators/easy_admin/card/card_generator.rb +94 -0
- data/lib/generators/easy_admin/card/templates/card_component.rb.erb +127 -0
- data/lib/generators/easy_admin/card/templates/card_component_spec.rb.erb +122 -0
- data/lib/generators/easy_admin/install/templates/easy_admin.rb +31 -0
- data/lib/generators/easy_admin/install_generator.rb +25 -0
- data/lib/generators/easy_admin/rbac/rbac_generator.rb +244 -0
- data/lib/generators/easy_admin/rbac/templates/add_rbac_to_admin_users.rb +23 -0
- data/lib/generators/easy_admin/rbac/templates/super_admin.rb +34 -0
- data/lib/generators/easy_admin/resource_generator.rb +43 -0
- data/lib/generators/easy_admin/templates/AUTH_README +35 -0
- data/lib/generators/easy_admin/templates/README +27 -0
- data/lib/generators/easy_admin/templates/create_easy_admin_admin_users.rb +45 -0
- data/lib/generators/easy_admin/templates/devise.rb +267 -0
- data/lib/generators/easy_admin/templates/easy_admin.rb +24 -0
- data/lib/generators/easy_admin/templates/resource.rb +29 -0
- data/lib/tasks/easy_admin_tasks.rake +4 -0
- metadata +445 -0
@@ -0,0 +1,244 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
|
4
|
+
module EasyAdmin
|
5
|
+
module Generators
|
6
|
+
class RbacGenerator < Rails::Generators::Base
|
7
|
+
include Rails::Generators::Migration
|
8
|
+
|
9
|
+
source_root File.expand_path('../templates', __FILE__)
|
10
|
+
|
11
|
+
desc 'Generate EasyAdmin Role-Based Access Control setup'
|
12
|
+
|
13
|
+
def self.next_migration_number(path)
|
14
|
+
Time.current.utc.strftime("%Y%m%d%H%M%S")
|
15
|
+
end
|
16
|
+
|
17
|
+
def copy_migration
|
18
|
+
migration_template(
|
19
|
+
'add_rbac_to_admin_users.rb',
|
20
|
+
'db/migrate/add_rbac_to_admin_users.rb',
|
21
|
+
migration_version: migration_version
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_role_models
|
26
|
+
template 'super_admin.rb', 'app/models/easy_admin/super_admin.rb'
|
27
|
+
template 'admin.rb', 'app/models/easy_admin/admin.rb'
|
28
|
+
template 'editor.rb', 'app/models/easy_admin/editor.rb'
|
29
|
+
template 'viewer.rb', 'app/models/easy_admin/viewer.rb'
|
30
|
+
end
|
31
|
+
|
32
|
+
def update_admin_user_model
|
33
|
+
inject_into_file 'app/models/easy_admin/admin_user.rb', after: "self.table_name = \"easy_admin_admin_users\"\n" do
|
34
|
+
<<-RUBY
|
35
|
+
|
36
|
+
# STI configuration for role-based access
|
37
|
+
self.inheritance_column = :type
|
38
|
+
|
39
|
+
# Associations
|
40
|
+
has_many :audit_logs, class_name: 'EasyAdmin::AuditLog', foreign_key: :admin_user_id, dependent: :destroy
|
41
|
+
|
42
|
+
# Scopes
|
43
|
+
scope :by_role, ->(role) { where(type: "EasyAdmin::\#{role}") }
|
44
|
+
|
45
|
+
# Cache permissions per request
|
46
|
+
def permissions_cache
|
47
|
+
@permissions_cache ||= {}
|
48
|
+
end
|
49
|
+
|
50
|
+
# Core authorization methods (to be overridden by subclasses)
|
51
|
+
def can_access_resource?(resource_name)
|
52
|
+
accessible_resources.include?(resource_name.to_s)
|
53
|
+
end
|
54
|
+
|
55
|
+
def can_perform_action?(resource_name, action)
|
56
|
+
return false unless can_access_resource?(resource_name)
|
57
|
+
allowed_actions_for(resource_name).include?(action.to_s)
|
58
|
+
end
|
59
|
+
|
60
|
+
def can_access_field?(resource_name, field_name, action = :read)
|
61
|
+
return false unless can_access_resource?(resource_name)
|
62
|
+
!restricted_fields_for(resource_name, action).include?(field_name.to_s)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Override in subclasses
|
66
|
+
def accessible_resources
|
67
|
+
[]
|
68
|
+
end
|
69
|
+
|
70
|
+
def allowed_actions_for(resource_name)
|
71
|
+
[:index, :show]
|
72
|
+
end
|
73
|
+
|
74
|
+
def restricted_fields_for(resource_name, action)
|
75
|
+
[]
|
76
|
+
end
|
77
|
+
|
78
|
+
def apply_resource_scope(resource_name, scope)
|
79
|
+
scope
|
80
|
+
end
|
81
|
+
|
82
|
+
# Helper for caching expensive operations
|
83
|
+
def cached_permission(key, &block)
|
84
|
+
permissions_cache[key] ||= block.call
|
85
|
+
end
|
86
|
+
RUBY
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def create_permission_cache
|
91
|
+
template 'permission_cache.rb', 'lib/easy_admin/permission_cache.rb'
|
92
|
+
end
|
93
|
+
|
94
|
+
def create_audit_log_model
|
95
|
+
template 'audit_log.rb', 'app/models/easy_admin/audit_log.rb'
|
96
|
+
|
97
|
+
migration_template(
|
98
|
+
'create_audit_logs.rb',
|
99
|
+
'db/migrate/create_easy_admin_audit_logs.rb',
|
100
|
+
migration_version: migration_version
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
def update_application_controller
|
105
|
+
inject_into_file 'app/controllers/easy_admin/application_controller.rb',
|
106
|
+
before: "include Pagy::Backend" do
|
107
|
+
<<-RUBY
|
108
|
+
class UnauthorizedError < StandardError; end
|
109
|
+
|
110
|
+
RUBY
|
111
|
+
end
|
112
|
+
|
113
|
+
inject_into_file 'app/controllers/easy_admin/application_controller.rb',
|
114
|
+
after: "before_action :authenticate_easy_admin_admin_user!\n" do
|
115
|
+
<<-RUBY
|
116
|
+
before_action :check_resource_access!, except: [:index]
|
117
|
+
|
118
|
+
rescue_from UnauthorizedError do |exception|
|
119
|
+
respond_to do |format|
|
120
|
+
format.html { redirect_to easy_admin.root_path, alert: 'You are not authorized to access this resource.' }
|
121
|
+
format.turbo_stream do
|
122
|
+
render turbo_stream: turbo_stream.replace("notifications",
|
123
|
+
EasyAdmin::NotificationComponent.new(
|
124
|
+
message: 'You are not authorized to access this resource',
|
125
|
+
type: :error
|
126
|
+
).call
|
127
|
+
)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
RUBY
|
132
|
+
end
|
133
|
+
|
134
|
+
inject_into_file 'app/controllers/easy_admin/application_controller.rb',
|
135
|
+
before: "def authenticate_admin_user!" do
|
136
|
+
<<-RUBY
|
137
|
+
def check_resource_access!
|
138
|
+
return unless defined?(@resource_class)
|
139
|
+
|
140
|
+
unless current_admin_user.can_access_resource?(@resource_class.resource_name)
|
141
|
+
raise UnauthorizedError, "Access denied to \#{@resource_class.resource_name}"
|
142
|
+
end
|
143
|
+
|
144
|
+
check_action_permission!
|
145
|
+
end
|
146
|
+
|
147
|
+
def check_action_permission!
|
148
|
+
action_map = {
|
149
|
+
'index' => :index,
|
150
|
+
'show' => :show,
|
151
|
+
'new' => :new,
|
152
|
+
'create' => :create,
|
153
|
+
'edit' => :edit,
|
154
|
+
'update' => :update,
|
155
|
+
'destroy' => :destroy,
|
156
|
+
'execute' => :batch_action
|
157
|
+
}
|
158
|
+
|
159
|
+
mapped_action = action_map[action_name] || action_name.to_sym
|
160
|
+
|
161
|
+
unless current_admin_user.can_perform_action?(@resource_class.resource_name, mapped_action)
|
162
|
+
raise UnauthorizedError, "Cannot perform \#{mapped_action} on \#{@resource_class.resource_name}"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def apply_role_scoping(scope)
|
167
|
+
current_admin_user.apply_resource_scope(@resource_class.resource_name, scope)
|
168
|
+
end
|
169
|
+
|
170
|
+
def permission_cache
|
171
|
+
@permission_cache ||= EasyAdmin::PermissionCache.new(current_admin_user)
|
172
|
+
end
|
173
|
+
|
174
|
+
RUBY
|
175
|
+
end
|
176
|
+
|
177
|
+
inject_into_file 'app/controllers/easy_admin/application_controller.rb',
|
178
|
+
after: "helper_method :current_admin_user, :admin_user_signed_in?" do
|
179
|
+
", :permission_cache"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def create_seeds
|
184
|
+
create_file 'db/seeds/easy_admin_rbac.rb', <<~RUBY
|
185
|
+
# Create default admin users with different roles
|
186
|
+
if Rails.env.development?
|
187
|
+
# Super Admin - full access
|
188
|
+
EasyAdmin::SuperAdmin.find_or_create_by(email: 'super@example.com') do |admin|
|
189
|
+
admin.password = 'password'
|
190
|
+
admin.password_confirmation = 'password'
|
191
|
+
admin.first_name = 'Super'
|
192
|
+
admin.last_name = 'Admin'
|
193
|
+
admin.confirmed_at = Time.current
|
194
|
+
end
|
195
|
+
|
196
|
+
# Standard Admin - most access except system settings
|
197
|
+
EasyAdmin::Admin.find_or_create_by(email: 'admin@example.com') do |admin|
|
198
|
+
admin.password = 'password'
|
199
|
+
admin.password_confirmation = 'password'
|
200
|
+
admin.first_name = 'Admin'
|
201
|
+
admin.last_name = 'User'
|
202
|
+
admin.confirmed_at = Time.current
|
203
|
+
end
|
204
|
+
|
205
|
+
# Editor - content management only
|
206
|
+
EasyAdmin::Editor.find_or_create_by(email: 'editor@example.com') do |admin|
|
207
|
+
admin.password = 'password'
|
208
|
+
admin.password_confirmation = 'password'
|
209
|
+
admin.first_name = 'Content'
|
210
|
+
admin.last_name = 'Editor'
|
211
|
+
admin.confirmed_at = Time.current
|
212
|
+
end
|
213
|
+
|
214
|
+
# Viewer - read-only access
|
215
|
+
EasyAdmin::Viewer.find_or_create_by(email: 'viewer@example.com') do |admin|
|
216
|
+
admin.password = 'password'
|
217
|
+
admin.password_confirmation = 'password'
|
218
|
+
admin.first_name = 'Read'
|
219
|
+
admin.last_name = 'Only'
|
220
|
+
admin.confirmed_at = Time.current
|
221
|
+
end
|
222
|
+
|
223
|
+
puts "EasyAdmin RBAC users created!"
|
224
|
+
puts "Roles available:"
|
225
|
+
puts " SuperAdmin - super@example.com / password (full access)"
|
226
|
+
puts " Admin - admin@example.com / password (standard admin)"
|
227
|
+
puts " Editor - editor@example.com / password (content only)"
|
228
|
+
puts " Viewer - viewer@example.com / password (read-only)"
|
229
|
+
end
|
230
|
+
RUBY
|
231
|
+
end
|
232
|
+
|
233
|
+
def show_readme
|
234
|
+
readme 'RBAC_README'
|
235
|
+
end
|
236
|
+
|
237
|
+
private
|
238
|
+
|
239
|
+
def migration_version
|
240
|
+
"[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class AddRbacToAdminUsers < ActiveRecord::Migration<%= migration_version %>
|
2
|
+
def change
|
3
|
+
# Add type column for STI
|
4
|
+
add_column :easy_admin_admin_users, :type, :string
|
5
|
+
add_column :easy_admin_admin_users, :permissions, :json, default: {}
|
6
|
+
add_column :easy_admin_admin_users, :resource_access, :json, default: {}
|
7
|
+
|
8
|
+
# Add indexes for performance
|
9
|
+
add_index :easy_admin_admin_users, :type
|
10
|
+
add_index :easy_admin_admin_users, [:type, :locked_at]
|
11
|
+
|
12
|
+
# Migrate existing users to Admin type
|
13
|
+
reversible do |dir|
|
14
|
+
dir.up do
|
15
|
+
execute <<-SQL
|
16
|
+
UPDATE easy_admin_admin_users
|
17
|
+
SET type = 'EasyAdmin::Admin'
|
18
|
+
WHERE type IS NULL
|
19
|
+
SQL
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module EasyAdmin
|
2
|
+
class SuperAdmin < AdminUser
|
3
|
+
def accessible_resources
|
4
|
+
cached_permission(:resources) do
|
5
|
+
EasyAdmin::ResourceRegistry.all_resources.map(&:resource_name)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def allowed_actions_for(resource_name)
|
10
|
+
[:index, :show, :new, :create, :edit, :update, :destroy, :batch_action, :row_action].map(&:to_s)
|
11
|
+
end
|
12
|
+
|
13
|
+
def restricted_fields_for(resource_name, action)
|
14
|
+
[] # No restrictions for super admin
|
15
|
+
end
|
16
|
+
|
17
|
+
def apply_resource_scope(resource_name, scope)
|
18
|
+
scope # No filtering for super admin
|
19
|
+
end
|
20
|
+
|
21
|
+
# Super admin specific methods
|
22
|
+
def super_admin?
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
def role_name
|
27
|
+
'Super Admin'
|
28
|
+
end
|
29
|
+
|
30
|
+
def role_badge_color
|
31
|
+
'red'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module EasyAdmin
|
2
|
+
module Generators
|
3
|
+
class ResourceGenerator < Rails::Generators::NamedBase
|
4
|
+
desc "Creates EasyAdmin resource for a model"
|
5
|
+
|
6
|
+
def self.source_root
|
7
|
+
@source_root ||= File.expand_path("templates", __dir__)
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_resource
|
11
|
+
template "resource.rb", "app/easy_admin/resources/#{file_name}_resource.rb"
|
12
|
+
end
|
13
|
+
|
14
|
+
def show_usage
|
15
|
+
say "\nResource created! Add it to your EasyAdmin configuration:", :green
|
16
|
+
say "\n # config/initializers/easy_admin.rb"
|
17
|
+
say " EasyAdmin.configure do |config|"
|
18
|
+
say " config.sidebar do"
|
19
|
+
say " item \"#{human_name.pluralize}\", easy_admin.#{route_key}_path, icon: \"📄\""
|
20
|
+
say " end"
|
21
|
+
say " end\n"
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def model_class_name
|
27
|
+
class_name
|
28
|
+
end
|
29
|
+
|
30
|
+
def route_key
|
31
|
+
file_name.pluralize
|
32
|
+
end
|
33
|
+
|
34
|
+
def resource_class_name
|
35
|
+
"#{class_name}Resource"
|
36
|
+
end
|
37
|
+
|
38
|
+
def human_name
|
39
|
+
class_name.humanize
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
===============================================================================
|
2
|
+
|
3
|
+
EasyAdmin Authentication Setup Complete!
|
4
|
+
|
5
|
+
===============================================================================
|
6
|
+
|
7
|
+
The EasyAdmin authentication system has been successfully installed.
|
8
|
+
|
9
|
+
What was added:
|
10
|
+
- Admin users migration (creates easy_admin_admin_users table)
|
11
|
+
- Devise configuration for EasyAdmin (config/initializers/easy_admin_devise.rb)
|
12
|
+
- EasyAdmin routes mounted at /admin
|
13
|
+
- Default admin user seeds (db/seeds/easy_admin.rb)
|
14
|
+
|
15
|
+
Next steps:
|
16
|
+
|
17
|
+
1. Run the migration:
|
18
|
+
rails db:migrate
|
19
|
+
|
20
|
+
2. Load the default admin user:
|
21
|
+
rails db:seed
|
22
|
+
|
23
|
+
3. Start your server and visit:
|
24
|
+
http://localhost:3000/admin
|
25
|
+
|
26
|
+
4. Sign in with the default credentials:
|
27
|
+
Email: admin@example.com
|
28
|
+
Password: password
|
29
|
+
|
30
|
+
5. (Optional) Configure email settings in config/initializers/easy_admin_devise.rb
|
31
|
+
for password reset functionality.
|
32
|
+
|
33
|
+
For more information, visit: https://github.com/your-username/easy_admin
|
34
|
+
|
35
|
+
===============================================================================
|
@@ -0,0 +1,27 @@
|
|
1
|
+
===============================================================================
|
2
|
+
|
3
|
+
EasyAdmin has been installed! 🎉
|
4
|
+
|
5
|
+
Next steps:
|
6
|
+
|
7
|
+
1. Configure your sidebar navigation in config/initializers/easy_admin.rb
|
8
|
+
2. Build the JavaScript assets: npm run build:js
|
9
|
+
3. Visit /easy_admin in your browser
|
10
|
+
|
11
|
+
Documentation:
|
12
|
+
- Sidebar DSL: Use `item` for navigation links and `group` for expandable sections
|
13
|
+
- Icons: Use emoji or any text-based icons
|
14
|
+
- Paths: Relative paths will be prefixed with your app's base URL
|
15
|
+
|
16
|
+
Example configuration:
|
17
|
+
|
18
|
+
config.sidebar do
|
19
|
+
item "Dashboard", dashboard_path, icon: "📊", active: current_page?(dashboard_path)
|
20
|
+
|
21
|
+
group "Content", icon: "📝" do
|
22
|
+
item "Posts", posts_path, icon: "📄"
|
23
|
+
item "Categories", categories_path, icon: "🏷️"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
===============================================================================
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class CreateEasyAdminAdminUsers < ActiveRecord::Migration<%= migration_version %>
|
2
|
+
def change
|
3
|
+
create_table :easy_admin_admin_users do |t|
|
4
|
+
## Database authenticatable
|
5
|
+
t.string :email, null: false, default: ""
|
6
|
+
t.string :encrypted_password, null: false, default: ""
|
7
|
+
|
8
|
+
## Personal Info
|
9
|
+
t.string :first_name
|
10
|
+
t.string :last_name
|
11
|
+
|
12
|
+
## Recoverable
|
13
|
+
t.string :reset_password_token
|
14
|
+
t.datetime :reset_password_sent_at
|
15
|
+
|
16
|
+
## Rememberable
|
17
|
+
t.datetime :remember_created_at
|
18
|
+
|
19
|
+
## Trackable
|
20
|
+
t.integer :sign_in_count, default: 0, null: false
|
21
|
+
t.datetime :current_sign_in_at
|
22
|
+
t.datetime :last_sign_in_at
|
23
|
+
t.string :current_sign_in_ip
|
24
|
+
t.string :last_sign_in_ip
|
25
|
+
|
26
|
+
## Confirmable
|
27
|
+
t.string :confirmation_token
|
28
|
+
t.datetime :confirmed_at
|
29
|
+
t.datetime :confirmation_sent_at
|
30
|
+
t.string :unconfirmed_email # Only if using reconfirmable
|
31
|
+
|
32
|
+
## Lockable
|
33
|
+
t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
|
34
|
+
t.string :unlock_token # Only if unlock strategy is :email or :both
|
35
|
+
t.datetime :locked_at
|
36
|
+
|
37
|
+
t.timestamps null: false
|
38
|
+
end
|
39
|
+
|
40
|
+
add_index :easy_admin_admin_users, :email, unique: true
|
41
|
+
add_index :easy_admin_admin_users, :reset_password_token, unique: true
|
42
|
+
add_index :easy_admin_admin_users, :confirmation_token, unique: true
|
43
|
+
add_index :easy_admin_admin_users, :unlock_token, unique: true
|
44
|
+
end
|
45
|
+
end
|