cbac 0.3.1
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.
- data/Manifest +44 -0
- data/README.rdoc +48 -0
- data/Rakefile +36 -0
- data/cbac.gemspec +31 -0
- data/generators/cbac/USAGE +34 -0
- data/generators/cbac/cbac_generator.rb +45 -0
- data/generators/cbac/templates/config/context_roles.rb +10 -0
- data/generators/cbac/templates/config/privileges.rb +30 -0
- data/generators/cbac/templates/controllers/generic_roles_controller.rb +30 -0
- data/generators/cbac/templates/controllers/memberships_controller.rb +22 -0
- data/generators/cbac/templates/controllers/permissions_controller.rb +42 -0
- data/generators/cbac/templates/fixtures/cbac_generic_roles.yml +9 -0
- data/generators/cbac/templates/fixtures/cbac_memberships.yml +8 -0
- data/generators/cbac/templates/fixtures/cbac_permissions.yml +8 -0
- data/generators/cbac/templates/migrate/create_cbac.rb +40 -0
- data/generators/cbac/templates/stylesheets/cbac.css +65 -0
- data/generators/cbac/templates/views/generic_roles/index.html.erb +59 -0
- data/generators/cbac/templates/views/layouts/cbac.html.erb +17 -0
- data/generators/cbac/templates/views/memberships/_update.html.erb +12 -0
- data/generators/cbac/templates/views/memberships/index.html.erb +22 -0
- data/generators/cbac/templates/views/permissions/_update_context_role.html.erb +12 -0
- data/generators/cbac/templates/views/permissions/_update_generic_role.html.erb +12 -0
- data/generators/cbac/templates/views/permissions/index.html.erb +31 -0
- data/init.rb +11 -0
- data/lib/cbac.rb +104 -0
- data/lib/cbac/config.rb +10 -0
- data/lib/cbac/context_role.rb +27 -0
- data/lib/cbac/generic_role.rb +6 -0
- data/lib/cbac/membership.rb +4 -0
- data/lib/cbac/permission.rb +6 -0
- data/lib/cbac/privilege.rb +72 -0
- data/lib/cbac/privilege_set.rb +28 -0
- data/lib/cbac/privilege_set_record.rb +5 -0
- data/lib/cbac/setup.rb +31 -0
- data/tasks/cbac.rake +19 -0
- data/test/fixtures/cbac_generic_roles.yml +9 -0
- data/test/fixtures/cbac_memberships.yml +8 -0
- data/test/fixtures/cbac_permissions.yml +15 -0
- data/test/fixtures/cbac_privilege_set.yml +18 -0
- data/test/test_cbac_authorize_context_roles.rb +43 -0
- data/test/test_cbac_authorize_generic_roles.rb +37 -0
- data/test/test_cbac_context_role.rb +51 -0
- data/test/test_cbac_privilege.rb +99 -0
- data/test/test_cbac_privilege_set.rb +52 -0
- metadata +118 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
/****
|
2
|
+
* General
|
3
|
+
*/
|
4
|
+
|
5
|
+
div.cbac h1 {
|
6
|
+
|
7
|
+
}
|
8
|
+
|
9
|
+
div.cbac table {
|
10
|
+
padding: 0px;
|
11
|
+
margin: 0px;
|
12
|
+
border-collapse: collapse;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.cbac div.linebreak {
|
16
|
+
height: 20px;
|
17
|
+
}
|
18
|
+
|
19
|
+
/****
|
20
|
+
* Table
|
21
|
+
*/
|
22
|
+
|
23
|
+
div.cbac th {
|
24
|
+
background-color: #ABEB71;
|
25
|
+
}
|
26
|
+
|
27
|
+
div.cbac td, div.cbac th {
|
28
|
+
border: 1px solid black;
|
29
|
+
}
|
30
|
+
|
31
|
+
div.cbac td.small, div.cbac th.small {
|
32
|
+
width: 50px;
|
33
|
+
}
|
34
|
+
|
35
|
+
div.cbac td.medium, div.cbac th.medium {
|
36
|
+
width: 150px;
|
37
|
+
}
|
38
|
+
|
39
|
+
div.cbac td.large, div.cbac th.large {
|
40
|
+
width: 600px;
|
41
|
+
}
|
42
|
+
|
43
|
+
div.cbac td.checked {
|
44
|
+
text-align: center;
|
45
|
+
}
|
46
|
+
|
47
|
+
div.cbac td.submit {
|
48
|
+
text-align: right;
|
49
|
+
}
|
50
|
+
|
51
|
+
/****
|
52
|
+
* Controls
|
53
|
+
*/
|
54
|
+
|
55
|
+
div.cbac input[type="text"] {
|
56
|
+
margin: 2px;
|
57
|
+
}
|
58
|
+
|
59
|
+
div.cbac td.medium input[type="text"] {
|
60
|
+
width: 138px;
|
61
|
+
}
|
62
|
+
|
63
|
+
div.cbac td.large input[type="text"] {
|
64
|
+
width: 588px;
|
65
|
+
}
|
@@ -0,0 +1,59 @@
|
|
1
|
+
<div class="cbac">
|
2
|
+
<h1>Generic roles</h1>
|
3
|
+
<table>
|
4
|
+
<tr>
|
5
|
+
<th class="medium">Name</th>
|
6
|
+
<th class="large">Remarks</th>
|
7
|
+
<th class="small"> </th>
|
8
|
+
</tr>
|
9
|
+
|
10
|
+
<% Cbac::GenericRole.find(:all).each do |role| %>
|
11
|
+
<tr class="row">
|
12
|
+
<% form_for role do |r| %>
|
13
|
+
<td class="medium"><%= r.text_field :name %></td>
|
14
|
+
<td class="large"><%= r.text_field :remarks, :rows => 1 %></td>
|
15
|
+
<td class="small"><%= r.submit "OK" %></td>
|
16
|
+
<% end %>
|
17
|
+
</tr>
|
18
|
+
<% end%>
|
19
|
+
</table>
|
20
|
+
|
21
|
+
<div class="linebreak"></div>
|
22
|
+
|
23
|
+
<table>
|
24
|
+
<% form_for(Cbac::GenericRole.new) do |new_role| %>
|
25
|
+
<tr class="row">
|
26
|
+
<th colspan="2">New generic role</th>
|
27
|
+
</tr>
|
28
|
+
<tr class="row">
|
29
|
+
<td class="medium">Name</td>
|
30
|
+
<td class="medium"><%= new_role.text_field :name %></td>
|
31
|
+
</tr>
|
32
|
+
<tr class="row">
|
33
|
+
<td class="medium">Remarks</td>
|
34
|
+
<td class="large"><%= new_role.text_field :remarks %></td>
|
35
|
+
</tr>
|
36
|
+
<tr class="row">
|
37
|
+
<td colspan="2" class="submit"><%= new_role.submit "Create" %></td>
|
38
|
+
</tr>
|
39
|
+
<% end %>
|
40
|
+
</table>
|
41
|
+
|
42
|
+
<div class="linebreak"></div>
|
43
|
+
|
44
|
+
<table>
|
45
|
+
<% form_tag(:controller => "cbac/generic_roles", :action => "delete") do |f| %>
|
46
|
+
<tr>
|
47
|
+
<th colspan="2">Delete generic role</th>
|
48
|
+
</tr>
|
49
|
+
<tr>
|
50
|
+
<td class="medium">Select role</td>
|
51
|
+
<td class="medium"><%= select_tag "id", Cbac::GenericRole.find(:all).collect{|role|"<option value='#{role.id}'>#{role.name}</option>"} %>
|
52
|
+
</td>
|
53
|
+
</tr>
|
54
|
+
<tr>
|
55
|
+
<td colspan="2" class="submit"><%= submit_tag "Delete" %></td>
|
56
|
+
</tr>
|
57
|
+
<% end %>
|
58
|
+
</table>
|
59
|
+
</div>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
|
+
<head>
|
6
|
+
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
7
|
+
<title>Context Based Access Control</title>
|
8
|
+
<%= javascript_include_tag :defaults %>
|
9
|
+
<%= stylesheet_link_tag "cbac" %>
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
<%= link_to "Permissions", cbac_permissions_path %>
|
13
|
+
<%= link_to "Generic roles", cbac_generic_roles_path %>
|
14
|
+
<%= link_to "Memberships", cbac_memberships_path %>
|
15
|
+
<%= yield %>
|
16
|
+
</body>
|
17
|
+
</html>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<% update_name = generic_role.id.to_s + "__" + user_id.to_s %>
|
2
|
+
<% unless update_partial %><div id="<%= update_name %>"><% end %>
|
3
|
+
<% remote_form_for "/cbac/memberships/update", :url => {:controller => "cbac/memberships", :action => "update"},
|
4
|
+
:update => update_name, :before => "$('#{update_name}').style.visibility = 'hidden';",
|
5
|
+
:complete => "$('#{update_name}').style.visibility = 'visible';" do %>
|
6
|
+
<%= hidden_field_tag "generic_role_id" + update_name, generic_role.id.to_s, :name => "generic_role_id" %>
|
7
|
+
<%= hidden_field_tag "user_id" + update_name, user_id.to_s, :name => "user_id" %>
|
8
|
+
<%= check_box_tag "member" + update_name, "1",
|
9
|
+
(Cbac::Membership.find(:all, :conditions => ["generic_role_id = ? AND user_id = ?", generic_role.id.to_s, user_id.to_s]).length > 0),
|
10
|
+
{:onclick => "this.form.onsubmit();", :name => "member"}%>
|
11
|
+
<% end %>
|
12
|
+
<% unless update_partial %></div><% end %>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<div class="cbac">
|
2
|
+
<h1>Memberships</h1>
|
3
|
+
<table>
|
4
|
+
<tr>
|
5
|
+
<th class="medium">Users</th>
|
6
|
+
<% @generic_roles.each do |role| %>
|
7
|
+
<th><%= role.name %></th>
|
8
|
+
<% end %>
|
9
|
+
</tr>
|
10
|
+
<% @users.each do |u| %>
|
11
|
+
<tr>
|
12
|
+
<td><%= u.name %></td>
|
13
|
+
<% @generic_roles.each do |generic_role| %>
|
14
|
+
<td class="checked">
|
15
|
+
<%= render :partial => "cbac/memberships/update.html", :locals => {:generic_role => generic_role,
|
16
|
+
:user_id => u.id.to_s,:update_partial => false} %>
|
17
|
+
</td>
|
18
|
+
<% end %>
|
19
|
+
</tr>
|
20
|
+
<% end %>
|
21
|
+
</table>
|
22
|
+
</div>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<% update_name = "cr__" + context_role.to_s + "__" + set_id.to_s %>
|
2
|
+
<% unless update_partial %><div id="<%= update_name %>"><% end %>
|
3
|
+
<% remote_form_for "/cbac/permissions/update", :url => cbac_permissions_update_path,
|
4
|
+
:update => update_name, :before => "$('#{update_name}').style.visibility = 'hidden';",
|
5
|
+
:complete => "$('#{update_name}').style.visibility = 'visible';" do %>
|
6
|
+
<%= hidden_field_tag "context_role" + update_name, context_role.to_s, :name => "context_role" %>
|
7
|
+
<%= hidden_field_tag "privilege_set_id" + update_name, set_id.to_s, :name => "privilege_set_id" %>
|
8
|
+
<%= check_box_tag "permission" + update_name, "1",
|
9
|
+
(Cbac::Permission.find(:all, :conditions => ["context_role = ? AND privilege_set_id = ?", context_role.to_s, set_id.to_s]).length > 0),
|
10
|
+
{:onclick => "this.form.onsubmit();", :name => "permission"}%>
|
11
|
+
<% end %>
|
12
|
+
<% unless update_partial %></div><% end %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<% update_name = "gr__" + role.id.to_s + "__" + set_id.to_s %>
|
2
|
+
<% unless update_partial %><div id="<%= update_name %>"><% end %>
|
3
|
+
<% remote_form_for "/cbac/permissions/update", :url => cbac_permissions_update_path,
|
4
|
+
:update => update_name, :before => "$('#{update_name}').style.visibility = 'hidden';",
|
5
|
+
:complete => "$('#{update_name}').style.visibility = 'visible';" do %>
|
6
|
+
<%= hidden_field_tag "generic_role_id" + update_name, role.id.to_s, :name => "generic_role_id" %>
|
7
|
+
<%= hidden_field_tag "privilege_set_id" + update_name, set_id.to_s, :name => "privilege_set_id" %>
|
8
|
+
<%= check_box_tag "permission" + update_name, "1",
|
9
|
+
(Cbac::Permission.find(:all, :conditions => ["generic_role_id = ? AND privilege_set_id = ?", role.id.to_s, set_id.to_s]).length > 0),
|
10
|
+
{:onclick => "this.form.onsubmit();", :name => "permission"}%>
|
11
|
+
<% end %>
|
12
|
+
<% unless update_partial %></div><% end %>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<div class="cbac">
|
2
|
+
<h1>Permissions</h1>
|
3
|
+
<table>
|
4
|
+
<tr>
|
5
|
+
<th>Privilegeset</th>
|
6
|
+
<% @context_roles.each do |name, comment| %>
|
7
|
+
<th><%= name %></th>
|
8
|
+
<% end %>
|
9
|
+
<% @generic_roles.each do |role| %>
|
10
|
+
<th><%= role.name %></th>
|
11
|
+
<% end %>
|
12
|
+
</tr>
|
13
|
+
<% PrivilegeSet.sets.each do |token, set| %>
|
14
|
+
<tr>
|
15
|
+
<td><%= set.name %></td>
|
16
|
+
<% @context_roles.each do |context_role, comment| %>
|
17
|
+
<td class="checked">
|
18
|
+
<%= render :partial => "cbac/permissions/update_context_role.html", :locals => {:context_role => context_role.to_s,
|
19
|
+
:set_id => set.id.to_s, :update_partial => false} %>
|
20
|
+
</td>
|
21
|
+
<% end %>
|
22
|
+
<% @generic_roles.each do |role| %>
|
23
|
+
<td class="checked">
|
24
|
+
<%= render :partial => "cbac/permissions/update_generic_role.html", :locals => {:role => role,
|
25
|
+
:set_id => set.id.to_s, :update_partial => false} %>
|
26
|
+
</td>
|
27
|
+
<% end %>
|
28
|
+
</tr>
|
29
|
+
<% end %>
|
30
|
+
</table>
|
31
|
+
</div>
|
data/init.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Configuration file
|
2
|
+
require File.dirname(__FILE__) + '/lib/cbac/config.rb'
|
3
|
+
|
4
|
+
# The following code contains configuration options. You can turn them on for
|
5
|
+
# gem development. For actual usage, it is advisable to set the configuration
|
6
|
+
# options in the environment files.
|
7
|
+
Cbac::Config.verbose = false
|
8
|
+
|
9
|
+
# Include CBAC core file
|
10
|
+
require File.dirname(__FILE__) + '/lib/cbac.rb'
|
11
|
+
|
data/lib/cbac.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# TODO: Check the permission table for double entries, ie: both an entry in the
|
2
|
+
# generic_role_id field and an entry in the context_role field. Solution: solve
|
3
|
+
# via model. Update model & add test
|
4
|
+
|
5
|
+
|
6
|
+
module Cbac
|
7
|
+
if Cbac::Setup.check
|
8
|
+
puts "CBAC properly installed"
|
9
|
+
|
10
|
+
require File.dirname(__FILE__) + '/cbac/privilege.rb'
|
11
|
+
require File.dirname(__FILE__) + '/cbac/privilege_set.rb'
|
12
|
+
require File.dirname(__FILE__) + '/cbac/context_role.rb'
|
13
|
+
|
14
|
+
# check performs a check to see if the user is allowed to access the given
|
15
|
+
# resource. Example: authorization_check("BlogController", "index", :get)
|
16
|
+
def authorization_check(controller, action, request, context = {})
|
17
|
+
# Determine the controller to look for
|
18
|
+
controller_method = [controller, action].join("/")
|
19
|
+
# Get the privilegesets
|
20
|
+
privilege_sets = Privilege.select(controller_method, request)
|
21
|
+
# Check the privilege sets
|
22
|
+
check_privilege_sets(privilege_sets, context)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Check the given privilege_set symbol
|
26
|
+
# TODO following code is not yet tested
|
27
|
+
def check_privilege_set(privilege_set, context = {})
|
28
|
+
check_privilege_sets([PrivilegeSet.sets[privilege_set.to_sym]], context)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Check the given privilege_sets
|
32
|
+
def check_privilege_sets(privilege_sets, context = {})
|
33
|
+
# Check the generic roles
|
34
|
+
return true if privilege_sets.any? { |set| Cbac::GenericRole.find(:all, :conditions => ["user_id= ? AND privilege_set_id = ?", current_user, set.id],:joins => [:generic_role_members, :permissions]).length > 0 }
|
35
|
+
# Check the context roles Get the permissions
|
36
|
+
privilege_sets.collect{|privilege_set|Cbac::Permission.find(:all, :conditions => ["privilege_set_id = ? AND generic_role_id = 0", privilege_set.id.to_s])}.flatten.each do |permission|
|
37
|
+
puts "Checking for context_role:#{permission.context_role} on privilege_set:#{permission.privilegeset.name}" if Cbac::Config.verbose
|
38
|
+
eval_string = ContextRole.roles[permission.context_role.to_sym]
|
39
|
+
# Not sure if this will work everywhere
|
40
|
+
return true if eval_string.call(context)
|
41
|
+
end
|
42
|
+
# not authorized
|
43
|
+
puts "Not authorized for: #{controller_method}" if Cbac::Config.verbose
|
44
|
+
false
|
45
|
+
end
|
46
|
+
|
47
|
+
# Code that performs authorization
|
48
|
+
def authorize
|
49
|
+
authorization_check(params[:controller], params[:action], request.request_method) || unauthorized
|
50
|
+
end
|
51
|
+
|
52
|
+
# Default unauthorized method Override this method to supply your own code
|
53
|
+
# for incorrect authorization
|
54
|
+
def unauthorized
|
55
|
+
render :text => "You are not authorized to perform this action", :status => 401
|
56
|
+
end
|
57
|
+
|
58
|
+
# Default implementation of the current_user method
|
59
|
+
def current_user
|
60
|
+
session[:currentuser].to_i
|
61
|
+
end
|
62
|
+
|
63
|
+
# Load controller classes and methods
|
64
|
+
def load_controller_methods
|
65
|
+
begin
|
66
|
+
Dir.glob("app/controllers/**/*.rb").each{|file| require file}
|
67
|
+
rescue LoadError
|
68
|
+
raise "Could not load controller classes"
|
69
|
+
end
|
70
|
+
# Make this iterative TODO
|
71
|
+
@classes = ApplicationController.subclasses
|
72
|
+
end
|
73
|
+
|
74
|
+
# Extracts the class name from the filename
|
75
|
+
def extract_class_name(filename)
|
76
|
+
File.basename(filename).chomp(".rb").camelize
|
77
|
+
end
|
78
|
+
|
79
|
+
# ### Initializer Include privileges file - contains the privilege and
|
80
|
+
# privilege definitions
|
81
|
+
begin
|
82
|
+
require File.join(RAILS_ROOT, "config", "privileges.rb")
|
83
|
+
rescue MissingSourceFile
|
84
|
+
puts "CBAC warning: Could not load config/privileges.rb (Did you run ./script/generate cbac)"
|
85
|
+
end
|
86
|
+
# Include context roles file - contains the context role definitions
|
87
|
+
begin
|
88
|
+
require File.join(RAILS_ROOT, "config", "context_roles.rb")
|
89
|
+
rescue MissingSourceFile
|
90
|
+
puts "CBAC warning: Could not load config/context_roles.rb (Did you run ./script/generate cbac)"
|
91
|
+
end
|
92
|
+
|
93
|
+
# ### Database autoload code
|
94
|
+
else
|
95
|
+
# This is the code that is executed if CBAc is not properly installed/
|
96
|
+
# configured. It includes a different authorize method, aimes at refusing
|
97
|
+
# all authorizations
|
98
|
+
def authorize
|
99
|
+
render :text => "Authorization error", :status => 401
|
100
|
+
false
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
data/lib/cbac/config.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
module Cbac
|
2
|
+
# Class containing configuration options for the Cbac system. The following
|
3
|
+
# configuration options are supported: verbose. Determines whether or not to
|
4
|
+
# output results to the console. All outputs are processed as puts commands.
|
5
|
+
class Config
|
6
|
+
class << self
|
7
|
+
attr_accessor :verbose
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# ContextRole is the class containing the context role definitions
|
2
|
+
#
|
3
|
+
# Usage: ContextRole.add :logged_in_user, "!session[:currentuser].nil?"
|
4
|
+
class ContextRole
|
5
|
+
class << self
|
6
|
+
# Hash containing all the context roles. Keys are the role names Values are
|
7
|
+
# the Ruby eval strings Eval strings must result in true or false
|
8
|
+
attr_reader :roles
|
9
|
+
|
10
|
+
# Adds a context role to the list of context roles. @symbol defines the name
|
11
|
+
# of the context role @context_rule defines the ruby code to be evaluated
|
12
|
+
# when determining role membership
|
13
|
+
#
|
14
|
+
# If the context role already exists, an exception is thrown.
|
15
|
+
def add(symbol, context_rule = "", &block)
|
16
|
+
symbol = symbol.to_sym
|
17
|
+
@roles = Hash.new if @roles.nil?
|
18
|
+
raise ArgumentError, "CBAC: ContextRole was already defined" if @roles.keys.include?(symbol)
|
19
|
+
# TODO following code
|
20
|
+
#raise ArgumentError, "CBAC: cannot specify both string rule and block rule" unless context_rule.nil? and block.nil?
|
21
|
+
# TODO context parameter in block statement is not explicitly tested
|
22
|
+
block = eval("Proc.new {|context| " + context_rule + "}") if block.nil?
|
23
|
+
@roles[symbol] = block
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,6 @@
|
|
1
|
+
class Cbac::GenericRole < ActiveRecord::Base
|
2
|
+
set_table_name "cbac_generic_roles"
|
3
|
+
|
4
|
+
has_many :generic_role_members, :class_name => "Cbac::Membership", :foreign_key => "generic_role_id"
|
5
|
+
has_many :permissions, :class_name => "Cbac::Permission", :foreign_key => "generic_role_id"
|
6
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
class Cbac::Permission < ActiveRecord::Base
|
2
|
+
set_table_name "cbac_permissions"
|
3
|
+
|
4
|
+
belongs_to :generic_role, :class_name => "Cbac::GenericRole", :foreign_key => "generic_role_id"
|
5
|
+
belongs_to :privilegeset, :class_name => "Cbac::PrivilegeSetRecord", :foreign_key => "privilege_set_id"
|
6
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# Class containing all the privileges
|
2
|
+
#
|
3
|
+
# To define a new controller method resource: Privilege.resource :privilegeset,
|
4
|
+
# "controller/method"
|
5
|
+
#
|
6
|
+
class Privilege
|
7
|
+
class << self
|
8
|
+
attr_reader :get_resources, :post_resources, :model_attributes, :models
|
9
|
+
|
10
|
+
# Links a resource with a PrivilegeSet
|
11
|
+
#
|
12
|
+
# An ArgumentError exception is thrown if the PrivilegeSet does not exist.
|
13
|
+
# To create PrivilegeSets, use the PrivilegeSet.add method
|
14
|
+
def resource(privilege_set, method, action="GET")
|
15
|
+
privilege_set = privilege_set.to_sym
|
16
|
+
@get_resources = Hash.new if @get_resources.nil?
|
17
|
+
@post_resources = Hash.new if @post_resources.nil?
|
18
|
+
action_aliases = {"GET" => ["GET", "get", "g","idempotent"], "POST" => ["POST", "post", "p"]}
|
19
|
+
raise ArgumentError, "CBAC: PrivilegeSet does not exist: #{privilege_set}" unless PrivilegeSet.sets.include?(privilege_set)
|
20
|
+
action_option = action_aliases.find { |name, aliases| aliases.include?(action.to_s) }
|
21
|
+
raise ArgumentError, "CBAC: Wrong value for argument 'action' in Privilege.resource: #{action}" if action_option.nil?
|
22
|
+
case action_option[0]
|
23
|
+
when "GET"
|
24
|
+
(@get_resources[method] ||= Array.new) << PrivilegeSet.sets[privilege_set]
|
25
|
+
when "POST"
|
26
|
+
(@post_resources[method] ||= Array.new) << PrivilegeSet.sets[privilege_set]
|
27
|
+
else
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def model_attribute
|
32
|
+
|
33
|
+
end
|
34
|
+
def model
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
# Finds the privilege sets associated with the given controller_method and
|
39
|
+
# action_type Valid values for action_type are "get", "post" and "put".
|
40
|
+
# "put" is converted into "post".
|
41
|
+
#
|
42
|
+
# If incorrect values are given for action_type the method will raise an
|
43
|
+
# ArgumentError. If the controller and action name are not found, an
|
44
|
+
# exception is being raised.
|
45
|
+
def select(controller_method, action_type)
|
46
|
+
action_type = action_type.to_s
|
47
|
+
post_methods = ["post", "put", "delete"]
|
48
|
+
if action_type == "get"
|
49
|
+
privilege_sets = Privilege.get_resources[controller_method]
|
50
|
+
else if post_methods.include?(action_type)
|
51
|
+
privilege_sets = Privilege.post_resources[controller_method]
|
52
|
+
else
|
53
|
+
raise ArgumentError, "CBAC: Incorrect action_type: #{action_type}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
# Error handling if no privilege_sets were found
|
57
|
+
if privilege_sets.nil?
|
58
|
+
if action_type == "get"
|
59
|
+
if !Privilege.post_resources[controller_method].nil?
|
60
|
+
raise "CBAC: PrivilegeSets only exist for other action: post on method: #{controller_method}"
|
61
|
+
end
|
62
|
+
else
|
63
|
+
if !Privilege.get_resources[controller_method].nil?
|
64
|
+
raise "CBAC: PrivilegeSets only exist for other action: get on method: #{controller_method}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
raise "CBAC: Could not find any privilege sets associated with: #{controller_method} and action: #{action_type}"
|
68
|
+
end
|
69
|
+
privilege_sets
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|