cccux 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/CHANGELOG.md +67 -0
- data/MIT-LICENSE +20 -0
- data/README.md +382 -0
- data/Rakefile +8 -0
- data/app/assets/config/cccux_manifest.js +1 -0
- data/app/assets/stylesheets/cccux/application.css +102 -0
- data/app/controllers/cccux/ability_permissions_controller.rb +271 -0
- data/app/controllers/cccux/application_controller.rb +37 -0
- data/app/controllers/cccux/authorization_controller.rb +10 -0
- data/app/controllers/cccux/cccux_controller.rb +64 -0
- data/app/controllers/cccux/dashboard_controller.rb +172 -0
- data/app/controllers/cccux/home_controller.rb +19 -0
- data/app/controllers/cccux/roles_controller.rb +290 -0
- data/app/controllers/cccux/simple_controller.rb +7 -0
- data/app/controllers/cccux/users_controller.rb +112 -0
- data/app/controllers/concerns/cccux/application_controller_concern.rb +32 -0
- data/app/helpers/cccux/application_helper.rb +4 -0
- data/app/helpers/cccux/authorization_helper.rb +228 -0
- data/app/jobs/cccux/application_job.rb +4 -0
- data/app/mailers/cccux/application_mailer.rb +6 -0
- data/app/models/cccux/ability.rb +142 -0
- data/app/models/cccux/ability_permission.rb +61 -0
- data/app/models/cccux/application_record.rb +5 -0
- data/app/models/cccux/role.rb +90 -0
- data/app/models/cccux/role_ability.rb +49 -0
- data/app/models/cccux/user_role.rb +42 -0
- data/app/models/concerns/cccux/authorizable.rb +25 -0
- data/app/models/concerns/cccux/scoped_ownership.rb +183 -0
- data/app/models/concerns/cccux/user_concern.rb +87 -0
- data/app/views/cccux/ability_permissions/edit.html.erb +58 -0
- data/app/views/cccux/ability_permissions/index.html.erb +108 -0
- data/app/views/cccux/ability_permissions/new.html.erb +308 -0
- data/app/views/cccux/dashboard/index.html.erb +69 -0
- data/app/views/cccux/dashboard/model_discovery.html.erb +148 -0
- data/app/views/cccux/home/index.html.erb +42 -0
- data/app/views/cccux/roles/_flash.html.erb +10 -0
- data/app/views/cccux/roles/_form.html.erb +78 -0
- data/app/views/cccux/roles/_role.html.erb +67 -0
- data/app/views/cccux/roles/edit.html.erb +317 -0
- data/app/views/cccux/roles/index.html.erb +51 -0
- data/app/views/cccux/roles/new.html.erb +3 -0
- data/app/views/cccux/roles/show.html.erb +99 -0
- data/app/views/cccux/users/edit.html.erb +117 -0
- data/app/views/cccux/users/index.html.erb +99 -0
- data/app/views/cccux/users/new.html.erb +94 -0
- data/app/views/cccux/users/show.html.erb +138 -0
- data/app/views/layouts/cccux/admin.html.erb +168 -0
- data/app/views/layouts/cccux/application.html.erb +17 -0
- data/app/views/shared/_footer.html.erb +101 -0
- data/config/routes.rb +63 -0
- data/db/migrate/20250626194001_create_cccux_roles.rb +15 -0
- data/db/migrate/20250626194007_create_cccux_ability_permissions.rb +18 -0
- data/db/migrate/20250626194011_create_cccux_user_roles.rb +13 -0
- data/db/migrate/20250626194016_create_cccux_role_abilities.rb +10 -0
- data/db/migrate/20250627170611_add_owned_to_cccux_role_abilities.rb +9 -0
- data/db/migrate/20250705193709_add_context_to_cccux_role_abilities.rb +9 -0
- data/db/migrate/20250706214415_add_ownership_configuration_to_role_abilities.rb +21 -0
- data/db/seeds.rb +136 -0
- data/lib/cccux/engine.rb +50 -0
- data/lib/cccux/version.rb +3 -0
- data/lib/cccux.rb +7 -0
- data/lib/tasks/cccux.rake +703 -0
- data/lib/tasks/view_helpers.rake +274 -0
- metadata +188 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: a2c04acd4a7bdb9bf56dd8bec3bff97fa96b47f311d99ad99ecc43f788ea86d2
|
|
4
|
+
data.tar.gz: 3aa15d6e9ede2db1c97356a67628a7c03f8ecee8b73af4578a86667d023ed0c6
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 67c23f642f404f7b04de4f7f28394d12bb46812fc4f63f126aaa8dea8087257cf353472cb4c9e924d497f381877fb94250144667c3c140eec23cb9f1ab2fc066
|
|
7
|
+
data.tar.gz: beb6ffdf77cafdfa83dd9e9f55a44c0aa45674c107cd4e24b100588577e337e1c67e0c299dcf839e7e9bef41b6e2f90cad1add1a4bb34fa6ab0914300c5c4972
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2025-07-07
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
#### Core Features
|
|
13
|
+
- **Role-Based Access Control (RBAC)**: Complete RBAC system with Users, Roles, and RoleAbilities models
|
|
14
|
+
- **Admin Interface**: Comprehensive admin controllers for managing users, roles, and permissions
|
|
15
|
+
- **CanCanCan Integration**: Seamless integration with CanCanCan authorization framework
|
|
16
|
+
- **Unified Ownership System**: Simplified ownership model supporting both direct and contextual ownership
|
|
17
|
+
|
|
18
|
+
#### Models
|
|
19
|
+
- `Cccux::User` - User management with role assignments
|
|
20
|
+
- `Cccux::Role` - Role definition and management
|
|
21
|
+
- `Cccux::RoleAbility` - Permission configuration with flexible ownership patterns
|
|
22
|
+
- `Cccux::UserRole` - Join table for user-role associations
|
|
23
|
+
|
|
24
|
+
#### Controllers
|
|
25
|
+
- `Cccux::UsersController` - User management interface
|
|
26
|
+
- `Cccux::RolesController` - Role creation and editing
|
|
27
|
+
- `Cccux::RoleAbilitiesController` - Permission configuration interface
|
|
28
|
+
- `Cccux::ApplicationControllerConcern` - Authorization concern for host applications
|
|
29
|
+
|
|
30
|
+
#### Setup and Configuration
|
|
31
|
+
- **Automated Setup Task**: `rails cccux:setup` for one-command installation
|
|
32
|
+
- **Status Task**: `rails cccux:status` for configuration verification
|
|
33
|
+
- **View Conversion Tool**: `rails cccux:convert_views[directory]` for automated view helper conversion
|
|
34
|
+
- **ApplicationController Integration**: Automatic configuration of authorization concerns
|
|
35
|
+
|
|
36
|
+
#### View Helpers
|
|
37
|
+
- `link_if_can_show` - Conditional show links based on permissions
|
|
38
|
+
- `link_if_can_edit` - Conditional edit links based on permissions
|
|
39
|
+
- `link_if_can_create` - Conditional create links based on permissions
|
|
40
|
+
- `button_if_can_destroy` - Conditional delete buttons based on permissions
|
|
41
|
+
- Support for nested resource routes and complex authorization patterns
|
|
42
|
+
|
|
43
|
+
#### Authorization Features
|
|
44
|
+
- **Flexible Ownership Configuration**: Support for multiple ownership patterns via UI
|
|
45
|
+
- **Contextual Permissions**: Users can have permissions within specific contexts (e.g., store managers)
|
|
46
|
+
- **Fallback Mechanisms**: Multiple ownership detection methods (custom `owned_by?`, `user_id`, `creator_id`)
|
|
47
|
+
- **Security by Default**: Deny access when no permissions are configured
|
|
48
|
+
|
|
49
|
+
#### Documentation
|
|
50
|
+
- Comprehensive README with setup instructions and examples
|
|
51
|
+
- Unified Ownership Guide explaining the simplified permission model
|
|
52
|
+
- Generators documentation for scaffolding
|
|
53
|
+
- Controller setup examples and best practices
|
|
54
|
+
|
|
55
|
+
### Technical Details
|
|
56
|
+
- **Rails Compatibility**: Supports Rails 7.1+
|
|
57
|
+
- **Ruby Compatibility**: Requires Ruby 3.0+
|
|
58
|
+
- **Database Agnostic**: Works with any Rails-supported database
|
|
59
|
+
- **Engine Architecture**: Implemented as a Rails engine for easy integration
|
|
60
|
+
- **Zeitwerk Compatible**: Fully compatible with Rails' autoloading system
|
|
61
|
+
|
|
62
|
+
### Migration Path
|
|
63
|
+
- Automatic migration from complex contextual/owned permission types to unified "owned" type
|
|
64
|
+
- Backward compatibility maintained during transition period
|
|
65
|
+
- Clear upgrade path for existing installations
|
|
66
|
+
|
|
67
|
+
[0.1.0]: https://github.com/bagus1/cccux/releases/tag/v0.1.0
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright Bagus1
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
# CCCUX - Simplified Role-Based Authorization Engine
|
|
2
|
+
|
|
3
|
+
CCCUX is a Rails engine that provides comprehensive role-based authorization with CanCanCan integration. It's designed to be **incredibly simple** - just add one line to your controllers and configure permissions through the web interface.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **One-Line Controller Setup**: Just add `load_and_authorize_resource` to any controller
|
|
8
|
+
- **No Model Code Required**: Models need no special concerns or methods
|
|
9
|
+
- **UI-Driven Configuration**: Set up complex ownership patterns through the web interface
|
|
10
|
+
- **Automatic Setup**: Configures your ApplicationController automatically
|
|
11
|
+
- **CanCanCan Integration**: Built on the proven CanCanCan authorization library
|
|
12
|
+
- **Flexible Ownership**: Handle simple user ownership or complex manager hierarchies
|
|
13
|
+
- **Admin Interface**: Clean, intuitive interface for role and permission management
|
|
14
|
+
- **Rails 8 Compatible**: Works with Rails 8 and modern Rails applications
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
### 1. Install the Engine
|
|
19
|
+
|
|
20
|
+
Add to your Gemfile:
|
|
21
|
+
```ruby
|
|
22
|
+
gem 'cccux', path: 'path/to/cccux'
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Run:
|
|
26
|
+
```bash
|
|
27
|
+
bundle install
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 2. Run the Setup Task
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
rails cccux:setup
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**What the setup task does:**
|
|
37
|
+
|
|
38
|
+
1. **Checks for Devise**: Verifies Devise is installed, guides you through installation if needed
|
|
39
|
+
2. **Mounts the Engine**: Adds `mount Cccux::Engine => '/cccux'` to your routes
|
|
40
|
+
3. **Configures ApplicationController**: Automatically adds the CCCUX authorization concern to your ApplicationController
|
|
41
|
+
4. **Creates Database Tables**: Runs migrations for roles, permissions, and user assignments
|
|
42
|
+
5. **Seeds Default Data**: Creates default roles (Guest, Basic User, Role Manager, Administrator)
|
|
43
|
+
6. **Creates Admin User**: Sets up a "Role Manager" user account for admin access
|
|
44
|
+
|
|
45
|
+
The setup task automatically configures your `ApplicationController` with:
|
|
46
|
+
- CanCanCan integration
|
|
47
|
+
- CCCUX Ability class
|
|
48
|
+
- Error handling for authorization failures
|
|
49
|
+
- View helpers for authorization checks
|
|
50
|
+
|
|
51
|
+
### 3. Add Authorization to Controllers
|
|
52
|
+
|
|
53
|
+
**The only requirement: Add `load_and_authorize_resource` to your controllers**
|
|
54
|
+
|
|
55
|
+
#### Basic Controller
|
|
56
|
+
```ruby
|
|
57
|
+
class ProductsController < ApplicationController
|
|
58
|
+
load_and_authorize_resource
|
|
59
|
+
|
|
60
|
+
def index
|
|
61
|
+
@products = @products.order(:name)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def show
|
|
65
|
+
# @product is automatically loaded and authorized
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
#### Nested Resource Controller
|
|
71
|
+
```ruby
|
|
72
|
+
class OrdersController < ApplicationController
|
|
73
|
+
# Load parent resource when present
|
|
74
|
+
load_and_authorize_resource :store, if: -> { params[:store_id].present? }
|
|
75
|
+
|
|
76
|
+
# Load main resource through parent or directly
|
|
77
|
+
load_and_authorize_resource :order, through: :store, if: -> { params[:store_id].present? }
|
|
78
|
+
load_and_authorize_resource :order, unless: -> { params[:store_id].present? }
|
|
79
|
+
|
|
80
|
+
def index
|
|
81
|
+
if params[:store_id].present?
|
|
82
|
+
@orders = @store.orders.order(:created_at)
|
|
83
|
+
else
|
|
84
|
+
@orders = @orders.order(:created_at)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 4. Configure Permissions
|
|
91
|
+
|
|
92
|
+
Start your server and navigate to `http://localhost:3000/cccux`:
|
|
93
|
+
|
|
94
|
+
1. **Model Discovery**: Click "Model Discovery" to automatically detect your models and create permissions
|
|
95
|
+
2. **Roles Management**: Go to "Roles" to see default roles and create custom ones
|
|
96
|
+
3. **Assign Permissions**: Configure which roles can perform which actions on your models
|
|
97
|
+
|
|
98
|
+
## Permission Configuration
|
|
99
|
+
|
|
100
|
+
CCCUX supports two access types:
|
|
101
|
+
|
|
102
|
+
### Global Access
|
|
103
|
+
- **What it does**: Access to all records everywhere
|
|
104
|
+
- **Use case**: Administrators, managers with broad access
|
|
105
|
+
- **Configuration**: Select "Global" access type
|
|
106
|
+
|
|
107
|
+
### Owned Access
|
|
108
|
+
- **What it does**: Access to records you own or have access to via relationships
|
|
109
|
+
- **Use case**: Users editing their own records, managers accessing records in their scope
|
|
110
|
+
- **Configuration**: Select "Owned" access type and configure ownership settings
|
|
111
|
+
|
|
112
|
+
## Ownership Configuration Examples
|
|
113
|
+
|
|
114
|
+
### Simple User Ownership
|
|
115
|
+
**Scenario**: Users can only edit products they created
|
|
116
|
+
|
|
117
|
+
- **Access Type**: Owned
|
|
118
|
+
- **Ownership Model**: (leave blank)
|
|
119
|
+
- **Foreign Key**: (leave blank - auto-detects `user_id`)
|
|
120
|
+
- **User Key**: (leave blank - defaults to `user_id`)
|
|
121
|
+
|
|
122
|
+
### Manager Ownership
|
|
123
|
+
**Scenario**: Store managers can edit all orders in stores they manage
|
|
124
|
+
|
|
125
|
+
- **Access Type**: Owned
|
|
126
|
+
- **Ownership Model**: `StoreManager`
|
|
127
|
+
- **Foreign Key**: `store_id`
|
|
128
|
+
- **User Key**: `user_id`
|
|
129
|
+
|
|
130
|
+
This configuration tells CCCUX: "Find all StoreManager records where user_id matches the current user, get their store_id values, and allow access to orders with those store_id values."
|
|
131
|
+
|
|
132
|
+
### Complex Hierarchies
|
|
133
|
+
**Scenario**: Regional managers can edit products in all stores in their region
|
|
134
|
+
|
|
135
|
+
- **Access Type**: Owned
|
|
136
|
+
- **Ownership Model**: `RegionalManager`
|
|
137
|
+
- **Foreign Key**: `region_id`
|
|
138
|
+
- **User Key**: `user_id`
|
|
139
|
+
|
|
140
|
+
## Model Requirements
|
|
141
|
+
|
|
142
|
+
**Models need NO special code!** CCCUX works with standard Rails models:
|
|
143
|
+
|
|
144
|
+
```ruby
|
|
145
|
+
class Order < ApplicationRecord
|
|
146
|
+
belongs_to :store
|
|
147
|
+
belongs_to :user
|
|
148
|
+
# That's it! No concerns, no special methods needed
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
class Product < ApplicationRecord
|
|
152
|
+
belongs_to :user
|
|
153
|
+
# Works with simple user_id ownership
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
class Store < ApplicationRecord
|
|
157
|
+
belongs_to :created_by, class_name: 'User'
|
|
158
|
+
has_many :store_managers
|
|
159
|
+
# CCCUX handles complex ownership through configuration
|
|
160
|
+
end
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**How it works:**
|
|
164
|
+
- CCCUX automatically detects `user_id` and `creator_id` columns for simple ownership
|
|
165
|
+
- Complex ownership patterns are handled through the UI configuration
|
|
166
|
+
- The CCCUX Ability class dynamically queries your join tables based on your settings
|
|
167
|
+
|
|
168
|
+
## View Helpers
|
|
169
|
+
|
|
170
|
+
CCCUX provides convenient view helpers that automatically handle authorization checks:
|
|
171
|
+
|
|
172
|
+
### Authorization-Aware Helpers
|
|
173
|
+
|
|
174
|
+
```erb
|
|
175
|
+
<!-- These helpers only render if user has permission -->
|
|
176
|
+
<%= link_if_can_show @product, "View Product", product_path(@product) %>
|
|
177
|
+
<%= link_if_can_edit @product, "Edit Product", edit_product_path(@product) %>
|
|
178
|
+
<%= link_if_can_create Product.new, "New Product", new_product_path %>
|
|
179
|
+
<%= button_if_can_destroy @product, "Delete", product_path(@product), method: :delete %>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Traditional CanCanCan Helpers
|
|
183
|
+
|
|
184
|
+
You can also use standard CanCanCan patterns:
|
|
185
|
+
|
|
186
|
+
```erb
|
|
187
|
+
<% if can? :read, @product %>
|
|
188
|
+
<%= link_to "View Product", product_path(@product) %>
|
|
189
|
+
<% end %>
|
|
190
|
+
|
|
191
|
+
<% if can? :update, @product %>
|
|
192
|
+
<%= link_to "Edit Product", edit_product_path(@product) %>
|
|
193
|
+
<% end %>
|
|
194
|
+
|
|
195
|
+
<% if can? :create, Product %>
|
|
196
|
+
<%= link_to "New Product", new_product_path %>
|
|
197
|
+
<% end %>
|
|
198
|
+
|
|
199
|
+
<% if can? :destroy, @product %>
|
|
200
|
+
<%= link_to "Delete", product_path(@product), method: :delete,
|
|
201
|
+
confirm: "Are you sure?" %>
|
|
202
|
+
<% end %>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Converting Existing Views
|
|
206
|
+
|
|
207
|
+
CCCUX includes a development tool to convert existing Rails views to use authorization helpers:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
# Convert all views in a directory
|
|
211
|
+
rails cccux:convert_views[app/views/products]
|
|
212
|
+
rails cccux:convert_views[app/views/stores]
|
|
213
|
+
|
|
214
|
+
# See conversion examples
|
|
215
|
+
rails cccux:view_examples
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**What it converts:**
|
|
219
|
+
- `link_to` patterns → `link_if_can_show`, `link_if_can_edit`
|
|
220
|
+
- `button_to` delete patterns → `button_if_can_destroy`
|
|
221
|
+
- "New" links → `link_if_can_create`
|
|
222
|
+
- Complex nested conditionals → context-aware helpers
|
|
223
|
+
- Handles nested resource routes automatically
|
|
224
|
+
|
|
225
|
+
**Example conversion:**
|
|
226
|
+
```erb
|
|
227
|
+
<!-- BEFORE -->
|
|
228
|
+
<% if @project %>
|
|
229
|
+
<%= link_to "Edit Task", edit_project_task_path(@project, @task) %>
|
|
230
|
+
<% else %>
|
|
231
|
+
<%= link_to "Edit Task", edit_task_path(@task) %>
|
|
232
|
+
<% end %>
|
|
233
|
+
|
|
234
|
+
<!-- AFTER -->
|
|
235
|
+
<%= link_if_can_edit @task, "Edit Task", @project ? edit_project_task_path(@project, @task) : edit_task_path(@task) %>
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
This conversion tool saves significant time when adding CCCUX to existing applications.
|
|
239
|
+
|
|
240
|
+
## Admin Interface
|
|
241
|
+
|
|
242
|
+
Navigate to `/cccux` to access the admin interface:
|
|
243
|
+
|
|
244
|
+
- **Dashboard**: Overview of roles, users, and permissions
|
|
245
|
+
- **Roles**: Create and manage roles with drag-and-drop priority ordering
|
|
246
|
+
- **Permissions**: View and create permissions for your models
|
|
247
|
+
- **Users**: Assign roles to users
|
|
248
|
+
- **Model Discovery**: Automatically detect new models and create permissions
|
|
249
|
+
|
|
250
|
+
## Error Handling
|
|
251
|
+
|
|
252
|
+
CCCUX automatically handles authorization errors:
|
|
253
|
+
|
|
254
|
+
- **Access Denied**: Redirects to root path with appropriate error message
|
|
255
|
+
- **Record Not Found**: Handles missing records gracefully
|
|
256
|
+
- **Admin Access**: Restricts admin interface to Role Managers only
|
|
257
|
+
|
|
258
|
+
## Testing
|
|
259
|
+
|
|
260
|
+
Test your authorization with standard Rails testing:
|
|
261
|
+
|
|
262
|
+
```ruby
|
|
263
|
+
class ProductsControllerTest < ActionDispatch::IntegrationTest
|
|
264
|
+
setup do
|
|
265
|
+
@user = users(:one)
|
|
266
|
+
@product = products(:one)
|
|
267
|
+
sign_in @user
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
test "should get index when authorized" do
|
|
271
|
+
@user.add_role('Basic User')
|
|
272
|
+
get products_url
|
|
273
|
+
assert_response :success
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
test "should deny access when not authorized" do
|
|
277
|
+
get products_url
|
|
278
|
+
assert_redirected_to root_path
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Advanced Usage
|
|
284
|
+
|
|
285
|
+
### Custom Ability Logic
|
|
286
|
+
|
|
287
|
+
If you need custom authorization logic, you can override the `current_ability` method in your controller:
|
|
288
|
+
|
|
289
|
+
```ruby
|
|
290
|
+
class ProductsController < ApplicationController
|
|
291
|
+
load_and_authorize_resource
|
|
292
|
+
|
|
293
|
+
private
|
|
294
|
+
|
|
295
|
+
def current_ability
|
|
296
|
+
# Add custom context for complex scenarios
|
|
297
|
+
context = {}
|
|
298
|
+
context[:store_id] = params[:store_id] if params[:store_id]
|
|
299
|
+
@current_ability ||= Cccux::Ability.new(current_user, context)
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Multiple Role Assignment
|
|
305
|
+
|
|
306
|
+
Users can have multiple roles, and permissions are cumulative:
|
|
307
|
+
|
|
308
|
+
```ruby
|
|
309
|
+
user.add_role('Basic User')
|
|
310
|
+
user.add_role('Store Manager')
|
|
311
|
+
user.roles # => ['Basic User', 'Store Manager']
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Checking Roles in Code
|
|
315
|
+
|
|
316
|
+
```ruby
|
|
317
|
+
current_user.has_role?('Role Manager') # => true/false
|
|
318
|
+
current_user.roles # => ['Basic User', 'Store Manager']
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Setup Task Details
|
|
322
|
+
|
|
323
|
+
The `rails cccux:setup` task performs these steps:
|
|
324
|
+
|
|
325
|
+
1. **Devise Check**: Ensures Devise is installed and configured
|
|
326
|
+
2. **Route Mounting**: Adds CCCUX routes to your application
|
|
327
|
+
3. **ApplicationController Configuration**: Automatically adds the CCCUX concern
|
|
328
|
+
4. **Database Setup**: Creates all necessary tables and indexes
|
|
329
|
+
5. **Default Data**: Seeds roles, permissions, and creates admin user
|
|
330
|
+
6. **Status Verification**: Confirms all components are properly configured
|
|
331
|
+
|
|
332
|
+
The setup task is idempotent - you can run it multiple times safely.
|
|
333
|
+
|
|
334
|
+
## Why CCCUX is Simple
|
|
335
|
+
|
|
336
|
+
Traditional authorization solutions require:
|
|
337
|
+
- Complex model concerns and methods
|
|
338
|
+
- Manual ability class configuration
|
|
339
|
+
- Custom ownership logic in every model
|
|
340
|
+
- Lots of boilerplate code
|
|
341
|
+
|
|
342
|
+
**CCCUX eliminates all of this:**
|
|
343
|
+
- ✅ One line per controller: `load_and_authorize_resource`
|
|
344
|
+
- ✅ No model code required
|
|
345
|
+
- ✅ UI-driven configuration
|
|
346
|
+
- ✅ Automatic setup and integration
|
|
347
|
+
- ✅ Works with standard Rails patterns
|
|
348
|
+
|
|
349
|
+
## Troubleshooting
|
|
350
|
+
|
|
351
|
+
### Common Issues
|
|
352
|
+
|
|
353
|
+
**"Access denied" for everything:**
|
|
354
|
+
- Check that your models have been discovered (visit `/cccux/permissions`)
|
|
355
|
+
- Verify user has appropriate roles assigned
|
|
356
|
+
- Ensure permissions are configured for the role
|
|
357
|
+
|
|
358
|
+
**Controllers not authorizing:**
|
|
359
|
+
- Make sure `load_and_authorize_resource` is added to the controller
|
|
360
|
+
- Check that the setup task configured your ApplicationController
|
|
361
|
+
|
|
362
|
+
**Complex ownership not working:**
|
|
363
|
+
- Verify ownership model, foreign key, and user key are correct
|
|
364
|
+
- Check that the join table exists and has the expected columns
|
|
365
|
+
- Test the ownership configuration in the Rails console
|
|
366
|
+
|
|
367
|
+
### Getting Help
|
|
368
|
+
|
|
369
|
+
1. Check the `/cccux/status` page for configuration issues
|
|
370
|
+
2. Review the Rails logs for authorization errors
|
|
371
|
+
3. Use the Rails console to test permissions: `current_user.can?(:read, Product)`
|
|
372
|
+
|
|
373
|
+
## Contributing
|
|
374
|
+
|
|
375
|
+
1. Fork the repository
|
|
376
|
+
2. Create a feature branch
|
|
377
|
+
3. Make your changes with tests
|
|
378
|
+
4. Submit a pull request
|
|
379
|
+
|
|
380
|
+
## License
|
|
381
|
+
|
|
382
|
+
This project is licensed under the MIT License.
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//= link_directory ../stylesheets/cccux .css
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
|
3
|
+
* listed below.
|
|
4
|
+
*
|
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
|
7
|
+
*
|
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
|
11
|
+
* It is generally better to create a new file per style scope.
|
|
12
|
+
*
|
|
13
|
+
*= require_tree .
|
|
14
|
+
*= require_self
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/* Action Button Styles */
|
|
18
|
+
.cccux-btn {
|
|
19
|
+
padding: 0.375rem 0.75rem;
|
|
20
|
+
text-decoration: none;
|
|
21
|
+
border-radius: 4px;
|
|
22
|
+
font-size: 0.875rem;
|
|
23
|
+
border: none;
|
|
24
|
+
cursor: pointer;
|
|
25
|
+
display: inline-block;
|
|
26
|
+
text-align: center;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.cccux-btn-view {
|
|
30
|
+
background: #17a2b8;
|
|
31
|
+
color: white;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.cccux-btn-view:hover {
|
|
35
|
+
background: #138496;
|
|
36
|
+
color: white;
|
|
37
|
+
text-decoration: none;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.cccux-btn-edit {
|
|
41
|
+
background: #ffc107;
|
|
42
|
+
color: #212529;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.cccux-btn-edit:hover {
|
|
46
|
+
background: #e0a800;
|
|
47
|
+
color: #212529;
|
|
48
|
+
text-decoration: none;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.cccux-btn-delete {
|
|
52
|
+
background: #dc3545;
|
|
53
|
+
color: white;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.cccux-btn-delete:hover {
|
|
57
|
+
background: #c82333;
|
|
58
|
+
color: white;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.cccux-btn-create {
|
|
62
|
+
background: #007bff;
|
|
63
|
+
color: white;
|
|
64
|
+
padding: 0.75rem 1.5rem;
|
|
65
|
+
font-weight: bold;
|
|
66
|
+
border-radius: 6px;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.cccux-btn-create:hover {
|
|
70
|
+
background: #0056b3;
|
|
71
|
+
color: white;
|
|
72
|
+
text-decoration: none;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* Button Group Utilities */
|
|
76
|
+
.cccux-btn-group {
|
|
77
|
+
display: flex;
|
|
78
|
+
gap: 0.5rem;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.cccux-btn-group-center {
|
|
82
|
+
display: flex;
|
|
83
|
+
gap: 0.5rem;
|
|
84
|
+
justify-content: center;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.cccux-btn-group-end {
|
|
88
|
+
display: flex;
|
|
89
|
+
gap: 0.5rem;
|
|
90
|
+
justify-content: flex-end;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* Size Variants */
|
|
94
|
+
.cccux-btn-sm {
|
|
95
|
+
padding: 0.25rem 0.5rem;
|
|
96
|
+
font-size: 0.75rem;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.cccux-btn-lg {
|
|
100
|
+
padding: 0.75rem 1.5rem;
|
|
101
|
+
font-size: 1rem;
|
|
102
|
+
}
|