rails-acu 2.2.0 → 3.0.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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +17 -16
  3. data/README.md +17 -2
  4. data/lib/acu/monitor.rb +18 -10
  5. data/lib/acu/rules.rb +8 -4
  6. data/lib/acu/utilities.rb +5 -1
  7. data/lib/acu/version.rb +1 -1
  8. data/spec/dummy/app/assets/javascripts/admin/booking/chats.js +2 -0
  9. data/spec/dummy/app/assets/javascripts/admin/booking/lists.js +2 -0
  10. data/spec/dummy/app/assets/stylesheets/admin/booking/chats.css +4 -0
  11. data/spec/dummy/app/assets/stylesheets/admin/booking/lists.css +4 -0
  12. data/spec/dummy/app/controllers/admin/booking/chats_controller.rb +58 -0
  13. data/spec/dummy/app/controllers/admin/booking/lists_controller.rb +9 -0
  14. data/spec/dummy/app/helpers/admin/booking/chats_helper.rb +2 -0
  15. data/spec/dummy/app/helpers/admin/booking/lists_helper.rb +2 -0
  16. data/spec/dummy/app/models/admin/booking.rb +5 -0
  17. data/spec/dummy/app/models/admin/booking/chat.rb +2 -0
  18. data/spec/dummy/app/models/admin/booking/list.rb +2 -0
  19. data/spec/dummy/app/views/admin/booking/chats/_form.html.erb +22 -0
  20. data/spec/dummy/app/views/admin/booking/chats/edit.html.erb +6 -0
  21. data/spec/dummy/app/views/admin/booking/chats/index.html.erb +27 -0
  22. data/spec/dummy/app/views/admin/booking/chats/new.html.erb +5 -0
  23. data/spec/dummy/app/views/admin/booking/chats/show.html.erb +9 -0
  24. data/spec/dummy/app/views/admin/booking/lists/_form.html.erb +22 -0
  25. data/spec/dummy/app/views/admin/booking/lists/edit.html.erb +6 -0
  26. data/spec/dummy/app/views/admin/booking/lists/index.html.erb +27 -0
  27. data/spec/dummy/app/views/admin/booking/lists/new.html.erb +5 -0
  28. data/spec/dummy/app/views/admin/booking/lists/show.html.erb +9 -0
  29. data/spec/dummy/config/routes.rb +12 -0
  30. data/spec/dummy/db/migrate/20170506054319_create_admin_booking_lists.rb +9 -0
  31. data/spec/dummy/db/migrate/20170506081928_create_admin_booking_chats.rb +9 -0
  32. data/spec/dummy/db/schema.rb +7 -1
  33. data/spec/dummy/spec/controllers/admin/booking/chats_controller_spec.rb +23 -0
  34. data/spec/dummy/spec/controllers/admin/booking/lists_controller_spec.rb +215 -0
  35. data/spec/dummy/spec/controllers/admin/manage_controller_spec.rb +6 -6
  36. data/spec/dummy/spec/controllers/home_controller_spec.rb +47 -47
  37. metadata +52 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1b2563936934989850c0e722493a76812b1fd6b6
4
- data.tar.gz: 1614f918ac20a0428122766f4d87009ef1ebffe5
3
+ metadata.gz: 0450675f2600156c12c47211f1675108244b1d30
4
+ data.tar.gz: a39ea7d9a539734311d0f0f38c72d2b5f0091129
5
5
  SHA512:
6
- metadata.gz: f13538958c6e64044bb04110c14bcfe6059bd844b82e7e0d80f84a7ca259015f0530c9e5b303347bd7224c236ad56adf4bcfd914d25c1e6839a3d17346d78ee2
7
- data.tar.gz: 176d26a870e35eb5ab33485811ccebf63d9ebc211c9a4913995efe0e734b15dea86cec662600a4262ff6834f7fb7cadff6c933e1bce197723881eab430bd8b7c
6
+ metadata.gz: be5b38572c20932cadadca6d14d519dd2d770305bb8b3f23bd88d769b526615bf4f286127c8e3b41be7eed8e14aa860f1bc4209fad2fc37a7949caaef5692b8f
7
+ data.tar.gz: 90401c33bd2b434f5eefa43821d82580e7da0bae588b04c96a8c858c01aab6177a56d7cecba429b34984b1e9e786eef791b46c5c808a96f7c2e2f0d2db3e1015
data/Gemfile.lock CHANGED
@@ -7,7 +7,7 @@ GIT
7
7
  PATH
8
8
  remote: .
9
9
  specs:
10
- rails-acu (2.2.0)
10
+ rails-acu (3.0.0)
11
11
  rails (~> 5.0.0, >= 5.0.0)
12
12
 
13
13
  GEM
@@ -72,7 +72,7 @@ GEM
72
72
  thor (>= 0.14, < 2.0)
73
73
  loofah (2.0.3)
74
74
  nokogiri (>= 1.5.9)
75
- mail (2.6.4)
75
+ mail (2.6.5)
76
76
  mime-types (>= 1.16, < 4)
77
77
  method_source (0.8.2)
78
78
  mime-types (3.1)
@@ -115,25 +115,26 @@ GEM
115
115
  rake (>= 0.8.7)
116
116
  thor (>= 0.18.1, < 2.0)
117
117
  rake (12.0.0)
118
- responders (2.3.0)
119
- railties (>= 4.2.0, < 5.1)
120
- rspec-core (3.5.4)
121
- rspec-support (~> 3.5.0)
122
- rspec-expectations (3.5.0)
118
+ responders (2.4.0)
119
+ actionpack (>= 4.2.0, < 5.3)
120
+ railties (>= 4.2.0, < 5.3)
121
+ rspec-core (3.6.0)
122
+ rspec-support (~> 3.6.0)
123
+ rspec-expectations (3.6.0)
123
124
  diff-lcs (>= 1.2.0, < 2.0)
124
- rspec-support (~> 3.5.0)
125
- rspec-mocks (3.5.0)
125
+ rspec-support (~> 3.6.0)
126
+ rspec-mocks (3.6.0)
126
127
  diff-lcs (>= 1.2.0, < 2.0)
127
- rspec-support (~> 3.5.0)
128
- rspec-rails (3.5.2)
128
+ rspec-support (~> 3.6.0)
129
+ rspec-rails (3.6.0)
129
130
  actionpack (>= 3.0)
130
131
  activesupport (>= 3.0)
131
132
  railties (>= 3.0)
132
- rspec-core (~> 3.5.0)
133
- rspec-expectations (~> 3.5.0)
134
- rspec-mocks (~> 3.5.0)
135
- rspec-support (~> 3.5.0)
136
- rspec-support (3.5.0)
133
+ rspec-core (~> 3.6.0)
134
+ rspec-expectations (~> 3.6.0)
135
+ rspec-mocks (~> 3.6.0)
136
+ rspec-support (~> 3.6.0)
137
+ rspec-support (3.6.0)
137
138
  sprockets (3.7.1)
138
139
  concurrent-ruby (~> 1.0)
139
140
  rack (> 1, < 3)
data/README.md CHANGED
@@ -87,6 +87,13 @@ Acu::Rules.define do
87
87
  }
88
88
  end
89
89
  end
90
+
91
+ # nested namespace (since v3.0.0)
92
+ namespace :admin do
93
+ namespace :chat do
94
+ allow :client
95
+ end
96
+ end
90
97
  end
91
98
  ```
92
99
 
@@ -95,7 +102,7 @@ As we define our rules at the first line, we have to say who are the entities? _
95
102
  Once we defined our entities we can set their binary access permissions at namespace/controller/action levels using `allow` and `deny` helpers. **that is it, we are done tutorialing; from now on is just tiny details. :)**
96
103
 
97
104
  > **Scenario:** We have a *public* site which serves to its client's; we have 2 namespaces on this site, one is the _default_ namespace with _home_ controller in it, and the second namespace belongs to the _admin_ of site which has many controllers and also a _contact_ controller.<br />
98
- We want to grant access to everyone for all of _home_ controller actions in _default_ namespace **except** the `some_secret_action1` and `some_secret_action2`; but these `some_secret_action*` can be accessed via the `:admin` and `:client` entities. By default only `:admin` can access to everywhere, but in namespace `admin` we made an exception for 2 actions in the `Admin::ContactController` which everyone can `send_message` to the admin and only clients can ask for `support`. Finally we want to grant access to everyone for _public_ controllers in our 2 namespaces _the default_ and _admin_. <br />
105
+ We want to grant access to everyone for all of _home_ controller actions in _default_ namespace **except** the `some_secret_action1` and `some_secret_action2`; but these `some_secret_action*` can be accessed via the `:admin` and `:client` entities. By default only `:admin` can access to everywhere, but in namespace `admin` we made an exception for 2 actions in the `Admin::ContactController` which everyone can `send_message` to the admin and only clients can ask for `support`. Finally we want to grant access to everyone for _public_ controllers in our 2 namespaces _the default_ and _admin_. Also clients can access to everything in namespace _chat_.<br />
99
106
  If you back trace it in the above example you can easily find this scenario in the rules, plain and simple.
100
107
 
101
108
  ### Gaurding the requests
@@ -129,7 +136,7 @@ acu_as [:admin, :client] do
129
136
  puts 'You are either `admin` or `client`'
130
137
  end
131
138
 
132
- # DO NOT executes the block if current user identified as either `:guest`
139
+ # DO NOT execute the block if current user identified as `:guest`
133
140
  acu_except [:guest] do
134
141
  puts 'Except `:guest`s anyone else can execute this code'
135
142
  end
@@ -240,6 +247,14 @@ defined in the `Acu::Rules.override` which enables the previously defined rule t
240
247
  [...]
241
248
  ```
242
249
 
250
+ ## Change Logs
251
+
252
+ ### v3.0.0
253
+ * Nested namespace support
254
+
255
+ ### Before `v3.0.0`
256
+ * Core functionalities implemented and stabilized
257
+
243
258
 
244
259
  ## Contributing
245
260
  In order contributing to this project:
data/lib/acu/monitor.rb CHANGED
@@ -38,16 +38,24 @@ module Acu
38
38
  {namespace: nil, controller: :namespace, action: :controller}.each do |current, parent|
39
39
  t = -1
40
40
  # either mentioned explicitly
41
- if cond[current]
42
- t = (cond[current][:name].to_s == eval("_info.#{current}").to_s) ? 1 : 0
41
+ if cond[current] and not cond[current].empty?
42
+ # hierarchical match `_info[current]` with `cond[current]` to support nested namespace (since v3.0.0)
43
+ cond[current].map { |c| c[:name].to_s }.each.with_index do |c, index|
44
+ t = (c == eval("_info.#{current}")[index].to_s) ? 1 : 0
45
+ break if t == 0
46
+ end
43
47
  # or in `only|except` tags
44
- elsif parent and cond[parent]
48
+ elsif parent and cond[parent] and not cond[parent].empty?
45
49
  # if nothing mentioned in parent, assume for all
46
- t = 1 if not(cond[parent][:only] or cond[parent][:except])
50
+ t = 1 if not cond[parent].map { |c| c[:only] or c[:except] }.all?
47
51
  # flag true if it checked in namespace's only tag
48
52
  {only: {on_true: 1, on_false: 0} , except: {on_true: 0, on_false: 1}}.each do |tag, val|
49
- if cond[parent][tag]
50
- case cond[parent][tag].include? eval("_info.#{current}").to_sym
53
+ # fetch all `tag` names
54
+ tag_list = cond[parent].map { |c| c[tag] }.flatten - [nil]
55
+ # if any tag is present?
56
+ if not tag_list.empty? and tag_list.any?
57
+ # if `current` is mentioned in `tag_list`?
58
+ case not (tag_list.map(&:to_s) & eval("_info.#{current}").map(&:to_s)).empty?
51
59
  when true
52
60
  t = val[:on_true]
53
61
  break
@@ -189,13 +197,13 @@ module Acu
189
197
  p = request[:parameters]
190
198
  # try find the namespace/controller set
191
199
  nc = p["controller"].split('/');
192
-
193
- n = nc.length > 1 ? nc.first : nil
194
- c = nc.length > 1 ? nc.second : nc.first
200
+ # considering multi layer namespaces
201
+ n = nc.length > 1 ? nc[0..-2] : nil
202
+ c = nc.length > 1 ? nc.last : nc.first
195
203
  a = p["action"]
196
204
 
197
205
  # return it with structure
198
- Struct.new(:namespace, :controller, :action).new(n, c, a)
206
+ Struct.new(:namespace, :controller, :action).new([n].flatten, [c].flatten, [a].flatten)
199
207
  end
200
208
 
201
209
  end # /class << self
data/lib/acu/rules.rb CHANGED
@@ -25,6 +25,7 @@ module Acu
25
25
 
26
26
  def reset
27
27
  @rules = { }
28
+ @_params = { }
28
29
  @entities = { }
29
30
  end
30
31
 
@@ -34,6 +35,7 @@ module Acu
34
35
  names = [nil] if names.empty?
35
36
  only = nil if only and not (only.kind_of?(Array) or only.length == 0)
36
37
  except = nil if except and not (except.kind_of?(Array) or except.length == 0)
38
+ raise Errors::AmbiguousRule.new("there is already an `except` or `only` constraints defined in container namespace `#{@_params[:namespace].map { |i| i[:name] }.join('::')}`") if (except or only) and @_params[:namespace] and @_params[:namespace].find { |n| n[:except] or n[:only] }
37
39
  raise Errors::AmbiguousRule.new('cannot have both `only` and `except` options at the same time for namespace(s) `%s`' %names.join(', ')) if only and except
38
40
  names.each do |name|
39
41
  pass namespace: { name: name ? name.downcase : name, except: except, only: only } do
@@ -48,7 +50,8 @@ module Acu
48
50
  names = [names].flatten if name
49
51
  only = nil if only and not (only.kind_of?(Array) or only.length == 0)
50
52
  except = nil if except and not (except.kind_of?(Array) or except.length == 0)
51
- raise Errors::AmbiguousRule.new("there is already an `except` or `only` constraints defined in container namespace `#{@_params[:namespace][:name]}`") if @_params[:namespace] and (@_params[:namespace][:except] || @_params[:namespace][:only])
53
+ raise Errors::InvalidSyntax.new("nested controllers are not allowed!") if @_params[:controller] and not @_params[:controller].empty?
54
+ raise Errors::AmbiguousRule.new("there is already an `except` or `only` constraints defined in container namespace `#{@_params[:namespace].map { |i| i[:name] }.join('::')}`") if @_params[:namespace] and @_params[:namespace].find { |n| n[:except] or n[:only] }
52
55
  raise Errors::AmbiguousRule.new('cannot have both `only` and `except` options at the same time for controller(s) `%s`' %names.join(', ')) if only and except
53
56
  names.each do |name|
54
57
  pass controller: { name: name.downcase, except: except, only: only } do
@@ -59,8 +62,9 @@ module Acu
59
62
 
60
63
  def action *names
61
64
  names = [names].flatten if name
65
+ raise Errors::InvalidSyntax.new("nested actions are not allowed!") if @_params[:action] and not @_params[:action].empty?
62
66
  raise Errors::AmbiguousRule.new("at least one of the parent `controller` or `namespace` needs to be defined for the this action") if not (@_params[:namespace] || @_params[:controller])
63
- raise Errors::AmbiguousRule.new("there is already an `except` or `only` constraints defined in container controller(s) `#{@_params[:controller][:name]}`") if @_params[:controller] and (@_params[:controller][:except] || @_params[:controller][:only])
67
+ raise Errors::AmbiguousRule.new("there is already an `except` or `only` constraints defined in container controller(s) `#{@_params[:controller].map { |i| i[:name] }.join('::')}`") if @_params[:controller] and @_params[:controller].find { |n| n[:except] or n[:only] }
64
68
  names.each do |name|
65
69
  pass action: { name: name.downcase } do
66
70
  yield
@@ -120,8 +124,8 @@ module Acu
120
124
  end
121
125
 
122
126
  def build_rule rule
123
- @rules[@_params.clone] ||= {}
124
- @rules[@_params.clone] = rules[@_params.clone].merge(rule);
127
+ @rules[@_params.deep_dup] ||= {}
128
+ @rules[@_params.deep_dup] = rules[@_params.clone].merge(rule);
125
129
  end
126
130
 
127
131
  def build_rule_entry
data/lib/acu/utilities.rb CHANGED
@@ -6,7 +6,11 @@ module Acu
6
6
  end
7
7
  def pass args = {}
8
8
  helper_initialize
9
- args.each { |k, v| @_params[k] = v }
9
+ args.each do |k, v|
10
+ @_params[k] ||= []
11
+ @_params[k] << v
12
+ @_params[k].flatten
13
+ end
10
14
  yield
11
15
  args.each { |k, _| @_params.delete k }
12
16
  end
data/lib/acu/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Acu
2
- VERSION = '2.2.0'
2
+ VERSION = '3.0.0'
3
3
  end
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,58 @@
1
+ class Admin::Booking::ChatsController < ApplicationController
2
+ before_action :set_admin_booking_chat, only: [:show, :edit, :update, :destroy]
3
+
4
+ # GET /admin/booking/chats
5
+ def index
6
+ @admin_booking_chats = Admin::Booking::Chat.all
7
+ end
8
+
9
+ # GET /admin/booking/chats/1
10
+ def show
11
+ end
12
+
13
+ # GET /admin/booking/chats/new
14
+ def new
15
+ @admin_booking_chat = Admin::Booking::Chat.new
16
+ end
17
+
18
+ # GET /admin/booking/chats/1/edit
19
+ def edit
20
+ end
21
+
22
+ # POST /admin/booking/chats
23
+ def create
24
+ @admin_booking_chat = Admin::Booking::Chat.new(admin_booking_chat_params)
25
+
26
+ if @admin_booking_chat.save
27
+ redirect_to @admin_booking_chat, notice: 'Chat was successfully created.'
28
+ else
29
+ render :new
30
+ end
31
+ end
32
+
33
+ # PATCH/PUT /admin/booking/chats/1
34
+ def update
35
+ if @admin_booking_chat.update(admin_booking_chat_params)
36
+ redirect_to @admin_booking_chat, notice: 'Chat was successfully updated.'
37
+ else
38
+ render :edit
39
+ end
40
+ end
41
+
42
+ # DELETE /admin/booking/chats/1
43
+ def destroy
44
+ @admin_booking_chat.destroy
45
+ redirect_to admin_booking_chats_url, notice: 'Chat was successfully destroyed.'
46
+ end
47
+
48
+ private
49
+ # Use callbacks to share common setup or constraints between actions.
50
+ def set_admin_booking_chat
51
+ @admin_booking_chat = Admin::Booking::Chat.find(params[:id])
52
+ end
53
+
54
+ # Only allow a trusted parameter "white list" through.
55
+ def admin_booking_chat_params
56
+ params.require(:admin_booking_chat).permit(:name)
57
+ end
58
+ end
@@ -0,0 +1,9 @@
1
+ class Admin::Booking::ListsController < ApplicationController
2
+ # GET /admin/booking/lists
3
+ def index
4
+ end
5
+
6
+ # GET /admin/booking/lists/1
7
+ def show
8
+ end
9
+ end
@@ -0,0 +1,2 @@
1
+ module Admin::Booking::ChatsHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module Admin::Booking::ListsHelper
2
+ end
@@ -0,0 +1,5 @@
1
+ module Admin::Booking
2
+ def self.table_name_prefix
3
+ 'admin_booking_'
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ class Admin::Booking::Chat < ApplicationRecord
2
+ end
@@ -0,0 +1,2 @@
1
+ class Admin::Booking::List < ApplicationRecord
2
+ end
@@ -0,0 +1,22 @@
1
+ <%= form_for(admin_booking_chat) do |f| %>
2
+ <% if admin_booking_chat.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(admin_booking_chat.errors.count, "error") %> prohibited this admin_booking_chat from being saved:</h2>
5
+
6
+ <ul>
7
+ <% admin_booking_chat.errors.full_messages.each do |message| %>
8
+ <li><%= message %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= f.label :name %>
16
+ <%= f.text_field :name %>
17
+ </div>
18
+
19
+ <div class="actions">
20
+ <%= f.submit %>
21
+ </div>
22
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing Admin Booking Chat</h1>
2
+
3
+ <%= render 'form', admin_booking_chat: @admin_booking_chat %>
4
+
5
+ <%= link_to 'Show', @admin_booking_chat %> |
6
+ <%= link_to 'Back', admin_booking_chats_path %>
@@ -0,0 +1,27 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <h1>Admin Booking Chats</h1>
4
+
5
+ <table>
6
+ <thead>
7
+ <tr>
8
+ <th>Name</th>
9
+ <th colspan="3"></th>
10
+ </tr>
11
+ </thead>
12
+
13
+ <tbody>
14
+ <% @admin_booking_chats.each do |admin_booking_chat| %>
15
+ <tr>
16
+ <td><%= admin_booking_chat.name %></td>
17
+ <td><%= link_to 'Show', admin_booking_chat %></td>
18
+ <td><%= link_to 'Edit', edit_admin_booking_chat_path(admin_booking_chat) %></td>
19
+ <td><%= link_to 'Destroy', admin_booking_chat, method: :delete, data: { confirm: 'Are you sure?' } %></td>
20
+ </tr>
21
+ <% end %>
22
+ </tbody>
23
+ </table>
24
+
25
+ <br>
26
+
27
+ <%= link_to 'New Admin Booking Chat', new_admin_booking_chat_path %>
@@ -0,0 +1,5 @@
1
+ <h1>New Admin Booking Chat</h1>
2
+
3
+ <%= render 'form', admin_booking_chat: @admin_booking_chat %>
4
+
5
+ <%= link_to 'Back', admin_booking_chats_path %>
@@ -0,0 +1,9 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <p>
4
+ <strong>Name:</strong>
5
+ <%= @admin_booking_chat.name %>
6
+ </p>
7
+
8
+ <%= link_to 'Edit', edit_admin_booking_chat_path(@admin_booking_chat) %> |
9
+ <%= link_to 'Back', admin_booking_chats_path %>
@@ -0,0 +1,22 @@
1
+ <%= form_for(admin_booking_list) do |f| %>
2
+ <% if admin_booking_list.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(admin_booking_list.errors.count, "error") %> prohibited this admin_booking_list from being saved:</h2>
5
+
6
+ <ul>
7
+ <% admin_booking_list.errors.full_messages.each do |message| %>
8
+ <li><%= message %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= f.label :name %>
16
+ <%= f.text_field :name %>
17
+ </div>
18
+
19
+ <div class="actions">
20
+ <%= f.submit %>
21
+ </div>
22
+ <% end %>