role_core 0.0.12 → 0.0.14

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: 161464a27b8e4e9f59ca62b95a6c975fec056196b48d1fe0a80e2d15618a368e
4
- data.tar.gz: 28f2cc4b103d2093893ce45a98ab91e63e878e4639889822eae5e710286660d3
3
+ metadata.gz: 2c75876caf7676f2733564e2f0657b8625c798d29ee7de9e45a21bc66312e54d
4
+ data.tar.gz: 8bfb27b3b34481cb4cf566d3ff336e9450b45020a9109a201d7ac21e1e81194f
5
5
  SHA512:
6
- metadata.gz: 4aaf5fe44a10e9448faec6c6ba0316ba446641238bd3c1d2e99fd29a950d43398e56ce1483edb7c0cb63d597fcccbf71dddb27aecd5e89e4dc0b3a6bb0999298
7
- data.tar.gz: 4a85faabeeccdd1b4b84459be9aea41459972edddddac5ce6dbcbb190084304f405380496cd731cf446ea2ae37a55ae04f02301b64e27fe997fa06e2b6d71412
6
+ metadata.gz: 3c4d3a8e2c38049412bc12f8e048093710ee3f929d9f6cac96525de98ecd6e1f8b4851792e905f8c0c2cc7a467a04cff9512c03d435d585b1c29c3e04b4fb437
7
+ data.tar.gz: fb14f0557dc1b7349b69e647297ebe3033b97138665b2c5314cccf5456933552aa6b0b6c906f258abf7a55be3f05e59e0e1a77ad26714151738e32e431da66bf
data/README.md CHANGED
@@ -1,13 +1,14 @@
1
1
  RoleCore
2
2
  ====
3
3
 
4
- A Rails engine providing essential industry of Role-based access control.
4
+ RoleCore is a Rails engine which could provide essential industry of Role-based access control.
5
5
 
6
6
  <img width="550" alt="2018-03-12 10 12 21" src="https://user-images.githubusercontent.com/5518/37262401-e6c9d604-25dd-11e8-849d-7f7d923d5f18.png">
7
7
 
8
- ## Usage
8
+ It's only provides the ability to define permissions and pre-made Role model.
9
9
 
10
- See demo for now.
10
+ In addition, it's not handle the authentication or authorization,
11
+ you should integrate with CanCanCan, Pundit or other solutions by yourself.
11
12
 
12
13
  ## Installation
13
14
 
@@ -17,13 +18,7 @@ Add this line to your Gemfile:
17
18
  gem 'role_core'
18
19
  ```
19
20
 
20
- Or you may want to include the gem directly from GitHub:
21
-
22
- ```ruby
23
- gem 'role_core', github: 'rails-engine/role_core'
24
- ```
25
-
26
- And then execute:
21
+ Then execute:
27
22
 
28
23
  ```sh
29
24
  $ bundle
@@ -41,8 +36,207 @@ Then do migrate
41
36
  $ bin/rails db:migrate
42
37
  ```
43
38
 
39
+ Run config generator
40
+
41
+ ```sh
42
+ $ bin/rails g role_core:config
43
+ ```
44
+
45
+ Run model generator
46
+
47
+ ```sh
48
+ $ bin/rails g role_core:model
49
+ ```
50
+
51
+ ## Getting Start
52
+
53
+ ### Define permissions
54
+
55
+ Permissions are defined in `config/initializers/role_core.rb`,
56
+ checking it to know how to define permissions.
57
+
58
+ In addition, there also includes a directive about how to integrate with CanCanCan.
59
+
60
+ ### Hook up to application
61
+
62
+ In order to obtain maximum customability, you need to hooking up role(s) to your user model by yourself.
63
+
64
+ #### For User who has single role
65
+
66
+ ##### Create `one-to-many` relationship between Role and User
67
+
68
+ Generate `one-to-many` migration, adding `role_id` to `User` model
69
+
70
+ ```sh
71
+ $ bin/rails g migration AddRoleToUsers role:references
72
+ ```
73
+
74
+ Then do migrate
75
+
76
+ ```sh
77
+ $ bin/rails db:migrate
78
+ ```
79
+
80
+ Declare `a User belongs to a Role`
81
+
82
+ ```ruby
83
+ class User < ApplicationRecord
84
+ belongs_to :role
85
+
86
+ # ...
87
+ end
88
+ ```
89
+
90
+ Declare `a Role has many Users`
91
+
92
+ ```ruby
93
+ class Role < RoleCore::Role
94
+ has_many :users
95
+ end
96
+ ```
97
+
98
+ ##### Check permission
99
+
100
+ Permssions you've defined will translate to a virtual model (a Class which implemented ActiveModel interface),
101
+ `permission` would be an attribute, `group` would be a nested virtual model (like ActiveRecord's `has_one` association).
102
+
103
+ So you can simply check permission like:
104
+
105
+ ```ruby
106
+ user.role.permissions.read_public?
107
+ user.role.permissions.project.read? # `project` is a `group`
108
+ ```
109
+
110
+ For better usage, you may delegate the `permissions` from `Role` model to `User`:
111
+
112
+ ```ruby
113
+ class User < ApplicationRecord
114
+ belongs_to :role
115
+
116
+ delegate :permissions, to: :role
117
+
118
+ # ...
119
+ end
120
+ ```
121
+
122
+ Then you can
123
+
124
+ ```ruby
125
+ user.permissions.read_public?
126
+ user.permissions.project.read?
127
+ ```
128
+
129
+ _Keep in mind: fetching `role` will made a SQL query, you may need eager loading to avoid N+1 problem in some cases._
130
+
131
+ #### For User who has multiple roles
132
+
133
+ ##### Create `many-to-many` relationship between Role and User
134
+
135
+ Generate a `many-to-many` intervening model
136
+
137
+ ```sh
138
+ $ bin/rails g model RoleAssignment user:references role:references
139
+ ```
140
+
141
+ Then do migrate
142
+
143
+ ```sh
144
+ $ bin/rails db:migrate
145
+ ```
146
+
147
+ Declare `a User has many Roles through RoleAssignments`
148
+
149
+ ```ruby
150
+ class User < ApplicationRecord
151
+ has_many :role_assignments, dependent: :destroy
152
+ has_many :roles, through: :role_assignments
153
+
154
+ # ...
155
+ end
156
+ ```
157
+
158
+ Declare `a Role has many Users through RoleAssignments`
159
+
160
+ ```ruby
161
+ class Role < RoleCore::Role
162
+ has_many :role_assignments, dependent: :destroy
163
+ has_many :users, through: :role_assignments
164
+ end
165
+ ```
166
+
167
+ ##### Check permission
168
+
169
+ Permssions you've defined will translate to a virtual model (a Class which implemented ActiveModel interface),
170
+ `permission` would be an attribute, `group` would be a nested virtual model (like ActiveRecord's `has_one` association).
171
+
172
+ So you can simply check permission like:
173
+
174
+ ```ruby
175
+ user.roles.any? { |role| role.permissions.read_public? }
176
+ user.roles.any? { |role| role.permissions.project.read? } # `project` is a `group`
177
+ ```
178
+
179
+ For better usage, you could declare a `can?` helper method:
180
+
181
+ ```ruby
182
+ class User < ApplicationRecord
183
+ has_many :role_assignments, dependent: :destroy
184
+ has_many :roles, through: :role_assignments
185
+
186
+ def can?(&block)
187
+ roles.map(&:permissions).any?(&block)
188
+ end
189
+
190
+ # ...
191
+ end
192
+ ```
193
+
194
+ Then you can
195
+
196
+ ```ruby
197
+ user.can? { |permissions| permissions.read_public? }
198
+ user.can? { |permissions| permissions.project.read? }
199
+ ```
200
+
201
+ _Keep in mind: fetching `roles` will made a SQL query, you may need eager loading to avoid N+1 problem in some cases._
202
+
203
+ ### Integrate with CanCanCan
204
+
205
+ Open `config/initializers/role_core.rb`, uncomment CanCanCan integration codes and follows samples to define permissions for CanCanCan
206
+
207
+ Open your User model:
208
+
209
+ - For a user who has single role:
210
+
211
+ Add a delegate to User model:
212
+
213
+ ```ruby
214
+ delegate :permitted_permissions, to: :role
215
+ ```
216
+
217
+ - For a user who has multiple roles:
218
+
219
+ Add a `permitted_permissions` public method to User model:
220
+
221
+ ```ruby
222
+ def permitted_permissions
223
+ roles.map(&:permitted_permissions).reduce(RoleCore::ComputedPermissions.new, &:concat)
224
+ end
225
+ ```
226
+
227
+ Open `app/models/ability.rb`, add `user.permitted_permissions.call(self, user)` to `initialize` method.
228
+
229
+ You can check RoleCore's Demo (see below) for better understanding.
230
+
231
+ ### Management UI
232
+
233
+ See [RolesController in dummy app](https://github.com/rails-engine/role_core/blob/master/test/dummy/app/controllers/roles_controller.rb)
234
+ and relates [view](https://github.com/rails-engine/role_core/blob/master/test/dummy/app/views/roles/_form.html.erb).
235
+
44
236
  ## Demo
45
237
 
238
+ The dummy app shows a simple multiple roles with CanCanCan integration includes management UI.
239
+
46
240
  Clone the repository.
47
241
 
48
242
  ```sh
@@ -0,0 +1,2 @@
1
+ Description:
2
+ The role_core:config generator creates RoleCore initializer and locale in the config directory.
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RoleCore
4
+ module Generators
5
+ class ConfigGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("../templates", __FILE__)
7
+
8
+ def generate_config
9
+ copy_file "role_core.rb", "config/initializers/role_core.rb"
10
+ copy_file "role_core.en.yml", "config/locales/role_core.en.yml"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ en:
2
+ role_core:
3
+ models: # Defined by `group` place here
4
+ # project: Project
5
+ # task: Task
6
+ attributes:
7
+ # global: # Top-level permissions
8
+ # foo: Foo
9
+ # bar: Bar
10
+ # project:
11
+ # create: New project
12
+ # destroy: Destroy project
13
+ # update: Edit project
14
+ # read: Read project
15
+ # read_public: Read public project
16
+ # task:
17
+ # create: New task
18
+ # destroy: Destroy task
19
+ # update: Edit task
20
+ # update_my_own: Edit my own task
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Uncomment below if you want to integrate with CanCanCan
4
+ #
5
+ # require "role_core/contrib/can_can_can_permission"
6
+ # RoleCore.permission_class = RoleCore::CanCanCanPermission
7
+
8
+ RoleCore.permission_set_class.draw do
9
+ # Define permissions for the application. For example:
10
+ #
11
+ # permission :foo, default: true # `default: true` means grant to user by default
12
+ # permission :bar
13
+ #
14
+ # You can also group permissions by using `group`:
15
+ #
16
+ # group :project do
17
+ # permission :create
18
+ # permission :destroy
19
+ # permission :update
20
+ # permission :read
21
+ # permission :read_public
22
+ #
23
+ # # `group` supports nesting
24
+ # group :task do
25
+ # permission :create
26
+ # permission :destroy
27
+ # permission :update
28
+ # permission :read
29
+ # end
30
+ # end
31
+ #
32
+ # For CanCanCan integration, you can pass `model_name` for `group` or `permission`. For example:
33
+ #
34
+ # group :project, model_name: "Project" do
35
+ # permission :create
36
+ # permission :destroy, model_name: 'Plan'
37
+ # end
38
+ #
39
+ # That will translate to CanCanCan's abilities (if user has these permissions),
40
+ # the permission's name will be the action:
41
+ #
42
+ # can :create, Project
43
+ # can :destroy, Plan
44
+ #
45
+ # You can pass `priority` argument to `permission`
46
+ #
47
+ # group :project, model_name: "Project" do
48
+ # permission :read_public,
49
+ # permission :read, priority: 1
50
+ # end
51
+ #
52
+ # That will made 'read' prior than `read_public`.
53
+ #
54
+ # For CanCanCan's hash of conditions
55
+ # (see https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities#hash-of-conditions)
56
+ # you can simply pass them as arguments for `permission` even with a block
57
+ #
58
+ # group :task, model_name: "Task" do
59
+ # permission :read_public, is_public: true
60
+ # permission :update_my_own, action: :update, default: true do |user, task|
61
+ # task.user_id == user.id
62
+ # end
63
+ # end
64
+ #
65
+ # Although permission's name will be CanCanCan's action by default,
66
+ # you can pass `action` argument to override it.
67
+ #
68
+ # permission :read_public, action: :read, is_public: true
69
+ #
70
+ end.finalize! # Call `finalize!` to freezing the definition, that's optional.
@@ -0,0 +1,2 @@
1
+ Description:
2
+ The role_core:model generator creates Role model for customizing in the app/models directory.
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RoleCore
4
+ module Generators
5
+ class ModelGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("../templates", __FILE__)
7
+
8
+ def generate_model
9
+ copy_file "role.rb", "app/models/role.rb"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Role < RoleCore::Role
4
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RoleCore
4
- VERSION = "0.0.12"
4
+ VERSION = "0.0.14"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: role_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.12
4
+ version: 0.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - jasl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-22 00:00:00.000000000 Z
11
+ date: 2018-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -44,7 +44,8 @@ dependencies:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0'
47
- description: A Rails engine providing essential industry of Role-based access control
47
+ description: RoleCore is a Rails engine which could provide essential industry of
48
+ Role-based access control.
48
49
  email:
49
50
  - jasl9187@hotmail.com
50
51
  executables: []
@@ -57,6 +58,13 @@ files:
57
58
  - app/models/role_core/application_record.rb
58
59
  - app/models/role_core/role.rb
59
60
  - db/migrate/20170705174003_create_roles.rb
61
+ - lib/generators/role_core/config/USAGE
62
+ - lib/generators/role_core/config/config_generator.rb
63
+ - lib/generators/role_core/config/templates/role_core.en.yml
64
+ - lib/generators/role_core/config/templates/role_core.rb
65
+ - lib/generators/role_core/model/USAGE
66
+ - lib/generators/role_core/model/model_generator.rb
67
+ - lib/generators/role_core/model/templates/role.rb
60
68
  - lib/role_core.rb
61
69
  - lib/role_core/computed_permissions.rb
62
70
  - lib/role_core/concerns/models/role.rb
@@ -90,5 +98,6 @@ rubyforge_project:
90
98
  rubygems_version: 2.7.6
91
99
  signing_key:
92
100
  specification_version: 4
93
- summary: A Rails engine providing essential industry of Role-based access control
101
+ summary: RoleCore is a Rails engine which could provide essential industry of Role-based
102
+ access control.
94
103
  test_files: []