cbac 0.3.1 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +60 -44
- data/Rakefile +2 -2
- data/cbac.gemspec +31 -31
- data/generators/cbac/cbac_generator.rb +27 -6
- data/generators/cbac/templates/config/cbac.pristine +2 -0
- data/generators/cbac/templates/controllers/permissions_controller.rb +21 -2
- data/generators/cbac/templates/controllers/upgrade_controller.rb +24 -0
- data/generators/cbac/templates/fixtures/cbac_memberships.yml +1 -1
- data/generators/cbac/templates/migrate/create_cbac_from_scratch.rb +59 -0
- data/generators/cbac/templates/migrate/create_cbac_upgrade_path.rb +31 -0
- data/generators/cbac/templates/tasks/cbac.rake +345 -0
- data/generators/cbac/templates/views/layouts/cbac.html.erb +2 -1
- data/generators/cbac/templates/views/memberships/index.html.erb +1 -1
- data/generators/cbac/templates/views/permissions/index.html.erb +14 -6
- data/generators/cbac/templates/views/upgrade/index.html.erb +32 -0
- data/lib/cbac.rb +23 -12
- data/lib/cbac/cbac_pristine/pristine.rb +133 -0
- data/lib/cbac/cbac_pristine/pristine_file.rb +158 -0
- data/lib/cbac/cbac_pristine/pristine_permission.rb +194 -0
- data/lib/cbac/cbac_pristine/pristine_role.rb +42 -0
- data/lib/cbac/known_permission.rb +14 -0
- data/lib/cbac/permission.rb +1 -1
- data/lib/cbac/privilege.rb +44 -0
- data/lib/cbac/privilege_set.rb +5 -4
- data/lib/cbac/privilege_set_record.rb +3 -1
- data/spec/cbac_pristine_file_spec.rb +329 -0
- data/spec/cbac_pristine_permission_spec.rb +358 -0
- data/spec/cbac_pristine_role_spec.rb +85 -0
- data/spec/rcov.opts +2 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +12 -0
- data/tasks/cbac.rake +345 -19
- data/test/test_cbac_privilege.rb +54 -0
- metadata +43 -9
- data/generators/cbac/templates/migrate/create_cbac.rb +0 -40
@@ -12,6 +12,7 @@
|
|
12
12
|
<%= link_to "Permissions", cbac_permissions_path %>
|
13
13
|
<%= link_to "Generic roles", cbac_generic_roles_path %>
|
14
14
|
<%= link_to "Memberships", cbac_memberships_path %>
|
15
|
+
<%= link_to "Upgrade", cbac_upgrade_path %>
|
15
16
|
<%= yield %>
|
16
17
|
</body>
|
17
|
-
</html>
|
18
|
+
</html>
|
@@ -1,25 +1,33 @@
|
|
1
1
|
<div class="cbac">
|
2
|
+
|
3
|
+
<h2>Subset:</h2>
|
4
|
+
<form action="<%= request.request_uri %>" method="get" name="subset_view_form">
|
5
|
+
<b>Privilege set</b> starts with: <input type="text" name="priv_substr" value="<%= params[:priv_substr] %>" /><br />
|
6
|
+
<b>Role</b> starts with: <input type="text" name="role_substr" value="<%= params[:role_substr] %>" /><br/>
|
7
|
+
<input type="submit" value="Submit" />
|
8
|
+
</form>
|
9
|
+
|
2
10
|
<h1>Permissions</h1>
|
3
11
|
<table>
|
4
12
|
<tr>
|
5
13
|
<th>Privilegeset</th>
|
6
|
-
<% @context_roles.each do |name, comment| %>
|
14
|
+
<% (@context_roles.sort { |x, y| x[0].to_s <=> y[0].to_s }).each do |name, comment| %>
|
7
15
|
<th><%= name %></th>
|
8
16
|
<% end %>
|
9
|
-
<% @generic_roles.each do |role| %>
|
17
|
+
<% (@generic_roles.sort { |x, y| x.name <=> y.name }).each do |role| %>
|
10
18
|
<th><%= role.name %></th>
|
11
19
|
<% end %>
|
12
20
|
</tr>
|
13
|
-
<%
|
21
|
+
<% (@sets.sort do |x,y| x[0].to_s <=> y[0].to_s end).each do |token, set| %>
|
14
22
|
<tr>
|
15
|
-
<td><%= set.name %></td>
|
16
|
-
<% @context_roles.each do |context_role, comment| %>
|
23
|
+
<td><span title ="<%= set.comment %>"><%= set.name %></span></td>
|
24
|
+
<% (@context_roles.sort { |x, y| x[0].to_s <=> y[0].to_s }).each do |context_role, comment| %>
|
17
25
|
<td class="checked">
|
18
26
|
<%= render :partial => "cbac/permissions/update_context_role.html", :locals => {:context_role => context_role.to_s,
|
19
27
|
:set_id => set.id.to_s, :update_partial => false} %>
|
20
28
|
</td>
|
21
29
|
<% end %>
|
22
|
-
<% @generic_roles.each do |role| %>
|
30
|
+
<% (@generic_roles.sort { |x, y| x.name <=> y.name }).each do |role| %>
|
23
31
|
<td class="checked">
|
24
32
|
<%= render :partial => "cbac/permissions/update_generic_role.html", :locals => {:role => role,
|
25
33
|
:set_id => set.id.to_s, :update_partial => false} %>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<div class="cbac">
|
2
|
+
<h1>Permissions: available upgrades</h1>
|
3
|
+
<span>Choose which of these available permissions you want to accept or reject.
|
4
|
+
Each upgrade either adds a new permission or revokes an existing permission.
|
5
|
+
You can also leave the available upgrade for another time.</span><br/><br/>
|
6
|
+
<% form_tag cbac_upgrade_update_path do %>
|
7
|
+
<table>
|
8
|
+
<tr>
|
9
|
+
<th class="medium">Add /revoke</th>
|
10
|
+
<th class="large">Privilegeset</th>
|
11
|
+
<th class="medium">Roletype</th>
|
12
|
+
<th class="medium">Role</th>
|
13
|
+
<th class="small">Accept</th>
|
14
|
+
<th class="small">Reject</th>
|
15
|
+
<th class="small">Leave</th>
|
16
|
+
</tr>
|
17
|
+
<% @permissions.each_with_index do |permission, index| %>
|
18
|
+
<tr>
|
19
|
+
<td><span><%=permission.operation_string.capitalize%></span><input type="hidden" name="permissions[<%=index.to_s%>][id]" value="<%=permission.id.to_s%>"/></td>
|
20
|
+
<td><span title='<%=permission.privilege_set.comment%>'><%=permission.privilege_set_name%></span></td>
|
21
|
+
<td><span><%=permission.pristine_role.role_type%></span></td>
|
22
|
+
<td><span><%=permission.pristine_role.name%></span></td>
|
23
|
+
<td><input type="radio" name="permissions[<%=index.to_s%>][action]" value="accept"/></td>
|
24
|
+
<td><input type="radio" name="permissions[<%=index.to_s%>][action]" value="reject"/></td>
|
25
|
+
<td><input type="radio" name="permissions[<%=index.to_s%>][action]" value="leave" checked="checked"/></td>
|
26
|
+
</tr>
|
27
|
+
<% end %>
|
28
|
+
</table>
|
29
|
+
<input type="button" value="Cancel" onclick="window.location.reload();"/>
|
30
|
+
<input type="submit" value="OK"/>
|
31
|
+
<% end %>
|
32
|
+
</div>
|
data/lib/cbac.rb
CHANGED
@@ -6,10 +6,13 @@
|
|
6
6
|
module Cbac
|
7
7
|
if Cbac::Setup.check
|
8
8
|
puts "CBAC properly installed"
|
9
|
-
|
10
|
-
require File.dirname(__FILE__)
|
11
|
-
require File.dirname(__FILE__)
|
12
|
-
require File.dirname(__FILE__)
|
9
|
+
|
10
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/cbac/privilege'))
|
11
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/cbac/privilege_set'))
|
12
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/cbac/context_role'))
|
13
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/cbac/cbac_pristine/pristine'))
|
14
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/cbac/cbac_pristine/pristine_file'))
|
15
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/cbac/cbac_pristine/pristine_permission'))
|
13
16
|
|
14
17
|
# check performs a check to see if the user is allowed to access the given
|
15
18
|
# resource. Example: authorization_check("BlogController", "index", :get)
|
@@ -31,13 +34,21 @@ module Cbac
|
|
31
34
|
# Check the given privilege_sets
|
32
35
|
def check_privilege_sets(privilege_sets, context = {})
|
33
36
|
# Check the generic roles
|
34
|
-
return true if privilege_sets.any? { |set| Cbac::GenericRole.find(:all, :conditions => ["user_id= ? AND privilege_set_id = ?",
|
37
|
+
return true if privilege_sets.any? { |set| Cbac::GenericRole.find(:all, :conditions => ["user_id= ? AND privilege_set_id = ?", current_user_id, set.id],:joins => [:generic_role_members, :permissions]).length > 0 }
|
35
38
|
# Check the context roles Get the permissions
|
36
39
|
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.
|
40
|
+
puts "Checking for context_role:#{permission.context_role} on privilege_set:#{permission.privilege_set.name}" if Cbac::Config.verbose
|
38
41
|
eval_string = ContextRole.roles[permission.context_role.to_sym]
|
39
42
|
# Not sure if this will work everywhere
|
40
|
-
|
43
|
+
# TODO: sort this out
|
44
|
+
context[:session] = session
|
45
|
+
context["session"] = session
|
46
|
+
begin
|
47
|
+
return true if eval_string.call(context)
|
48
|
+
rescue Exception => e
|
49
|
+
puts "Error in context role: #{permission.context_role} on privilege_set: #{permission.privilege_set.name}. Context: #{context}"
|
50
|
+
raise e if RAILS_ENV == "development" or RAILS_ENV == "test" # In development mode, this should crash as hard as possible, but in further stages, it should not
|
51
|
+
end
|
41
52
|
end
|
42
53
|
# not authorized
|
43
54
|
puts "Not authorized for: #{controller_method}" if Cbac::Config.verbose
|
@@ -56,7 +67,7 @@ module Cbac
|
|
56
67
|
end
|
57
68
|
|
58
69
|
# Default implementation of the current_user method
|
59
|
-
def
|
70
|
+
def current_user_id
|
60
71
|
session[:currentuser].to_i
|
61
72
|
end
|
62
73
|
|
@@ -79,15 +90,15 @@ module Cbac
|
|
79
90
|
# ### Initializer Include privileges file - contains the privilege and
|
80
91
|
# privilege definitions
|
81
92
|
begin
|
82
|
-
require File.join(RAILS_ROOT, "config", "privileges.rb")
|
93
|
+
require File.join(RAILS_ROOT, "config", "cbac", "privileges.rb")
|
83
94
|
rescue MissingSourceFile
|
84
|
-
puts "CBAC warning: Could not load config/privileges.rb (Did you run ./script/generate cbac)"
|
95
|
+
puts "CBAC warning: Could not load config/cbac/privileges.rb (Did you run ./script/generate cbac?)"
|
85
96
|
end
|
86
97
|
# Include context roles file - contains the context role definitions
|
87
98
|
begin
|
88
|
-
require File.join(RAILS_ROOT, "config", "context_roles.rb")
|
99
|
+
require File.join(RAILS_ROOT, "config", "cbac", "context_roles.rb")
|
89
100
|
rescue MissingSourceFile
|
90
|
-
puts "CBAC warning: Could not load config/context_roles.rb (Did you run ./script/generate cbac)"
|
101
|
+
puts "CBAC warning: Could not load config/cbac/context_roles.rb (Did you run ./script/generate cbac?)"
|
91
102
|
end
|
92
103
|
|
93
104
|
# ### Database autoload code
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'pristine_file'))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'pristine_permission'))
|
3
|
+
|
4
|
+
module Cbac
|
5
|
+
module CbacPristine
|
6
|
+
#creates a yml file containing all generic roles from the specified pristine file objects
|
7
|
+
def create_generic_role_fixtures_file(pristine_files, fixtures_file_name)
|
8
|
+
roles = []
|
9
|
+
|
10
|
+
pristine_files.each do |pristine_file|
|
11
|
+
#if the pristine file wasn't parsed yet, we'll do it here
|
12
|
+
pristine_file.parse(false) if pristine_file.permissions.empty?
|
13
|
+
pristine_file.generic_roles.each do |generic_role|
|
14
|
+
# we only want the unique generic roles, because the yml file cannot have duplicates
|
15
|
+
has_role = false
|
16
|
+
roles.each do |role|
|
17
|
+
if role.name == generic_role.name
|
18
|
+
has_role = true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
roles.push(generic_role) unless has_role
|
22
|
+
end
|
23
|
+
end
|
24
|
+
create_fixtures_file(roles, fixtures_file_name)
|
25
|
+
end
|
26
|
+
|
27
|
+
# creates a yml file containing all cbac_permissions from the specified pristine file objects
|
28
|
+
def create_permissions_fixtures_file(pristine_files, fixtures_file_name)
|
29
|
+
permissions = []
|
30
|
+
|
31
|
+
pristine_files.each do |pristine_file|
|
32
|
+
pristine_file.parse(false) if pristine_file.permissions.empty?
|
33
|
+
pristine_file.permission_set.each do |line|
|
34
|
+
permissions.push(line)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
create_fixtures_file(permissions, fixtures_file_name)
|
38
|
+
end
|
39
|
+
|
40
|
+
# turns the fixtures into yml and writes them to a file with specified name.
|
41
|
+
def create_fixtures_file(fixtures, fixtures_file_name)
|
42
|
+
File.delete(fixtures_file_name) if File.exists?(fixtures_file_name)
|
43
|
+
f = File.new(fixtures_file_name, "w")
|
44
|
+
flock(f, File::LOCK_EX) do |f|
|
45
|
+
fixtures.each_with_index do |fixture, index|
|
46
|
+
f.write(fixture.to_yml_fixture(index + 1))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# set all cbac permissions and generic roles to the state in the specified pristine file objects
|
52
|
+
def set_pristine_state(pristine_files, clear_tables)
|
53
|
+
clear_cbac_tables if clear_tables
|
54
|
+
pristine_files.each do |pristine_file|
|
55
|
+
pristine_file.parse if pristine_file.permissions.empty?
|
56
|
+
pristine_file.permissions.each do |permission|
|
57
|
+
permission.accept
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# stage all unknown cbac_permissions
|
63
|
+
def stage_permissions(pristine_files)
|
64
|
+
|
65
|
+
pristine_files.each do |pristine_file|
|
66
|
+
pristine_file.parse(true) if pristine_file.permissions.empty?
|
67
|
+
pristine_file.permissions.each do |permission|
|
68
|
+
permission.stage
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def clear_cbac_tables
|
74
|
+
Cbac::GenericRole.delete_all
|
75
|
+
Cbac::Membership.delete_all
|
76
|
+
Cbac::Permission.delete_all
|
77
|
+
Cbac::KnownPermission.delete_all
|
78
|
+
Cbac::CbacPristine::PristinePermission.delete_all
|
79
|
+
Cbac::CbacPristine::PristineRole.delete_all
|
80
|
+
end
|
81
|
+
|
82
|
+
def delete_generic_known_permissions
|
83
|
+
known_permissions = Cbac::KnownPermission.find(:all, :conditions => {:permission_type => Cbac::KnownPermission.PERMISSION_TYPES[:generic]})
|
84
|
+
known_permissions.each { |p| p.destroy }
|
85
|
+
end
|
86
|
+
|
87
|
+
def delete_generic_permissions
|
88
|
+
permissions = Cbac::Permission.find(:all, :conditions => {:context_role => nil})
|
89
|
+
(permissions.select { |perm| perm.generic_role.name != "administrators" }).each { |p| p.destroy }
|
90
|
+
end
|
91
|
+
|
92
|
+
def delete_non_generic_staged_permissions
|
93
|
+
PristinePermission.delete_non_generic_permissions
|
94
|
+
end
|
95
|
+
|
96
|
+
def delete_generic_staged_permissions
|
97
|
+
PristinePermission.delete_generic_permissions
|
98
|
+
end
|
99
|
+
|
100
|
+
def database_contains_cbac_data?
|
101
|
+
return (Cbac::GenericRole.count != 0 or Cbac::Membership.count != 0 or Cbac::Permission.count != 0 or Cbac::KnownPermission.count != 0 or Cbac::CbacPristine::PristinePermission.count != 0 or Cbac::CbacPristine::PristineRole.count != 0)
|
102
|
+
end
|
103
|
+
|
104
|
+
def create_generic_pristine_file(file_name)
|
105
|
+
GenericPristineFile.new(file_name)
|
106
|
+
end
|
107
|
+
|
108
|
+
def create_pristine_file(file_name)
|
109
|
+
PristineFile.new(file_name)
|
110
|
+
end
|
111
|
+
|
112
|
+
def number_of_generic_staged_permissions
|
113
|
+
PristinePermission.count_generic_permissions
|
114
|
+
end
|
115
|
+
|
116
|
+
def number_of_non_generic_staged_permissions
|
117
|
+
PristinePermission.count_non_generic_permissions
|
118
|
+
end
|
119
|
+
|
120
|
+
def flock(file, mode)
|
121
|
+
success = file.flock(mode)
|
122
|
+
if success
|
123
|
+
begin
|
124
|
+
yield file
|
125
|
+
ensure
|
126
|
+
file.flock(File::LOCK_UN)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
return success
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'pristine_role'))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'pristine_permission'))
|
3
|
+
|
4
|
+
module Cbac
|
5
|
+
module CbacPristine
|
6
|
+
class AbstractPristineFile
|
7
|
+
attr_accessor :file_name, :permissions, :generic_roles
|
8
|
+
|
9
|
+
def initialize(file_name)
|
10
|
+
@file_name = file_name
|
11
|
+
@generic_roles = []
|
12
|
+
@permissions = []
|
13
|
+
@admin_role = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse(use_db = true)
|
17
|
+
@permissions = Array.new
|
18
|
+
|
19
|
+
f = File.open(@file_name, "r")
|
20
|
+
last_row_number = -1
|
21
|
+
f.each_with_index do |l, line_number|
|
22
|
+
pristine_permission = PristinePermission.new
|
23
|
+
permission_line = l.chomp
|
24
|
+
# if this is not a line we can convert into a permission, go to next line (or fail.....)
|
25
|
+
next unless is_pristine_permission_line?(permission_line, line_number)
|
26
|
+
|
27
|
+
# check if the row numbers are constructed properly.
|
28
|
+
# this is needed for migration purposes, each permission should have an unique and persistent row number
|
29
|
+
header_match = permission_line.match(/^(\d+):([\+-x]|=>):\s*/)
|
30
|
+
pristine_permission.line_number = header_match.captures[0].to_i
|
31
|
+
if pristine_permission.line_number != last_row_number.succ
|
32
|
+
raise SyntaxError, "Error: row numbers in pristine file do not increase monotonously"
|
33
|
+
else
|
34
|
+
last_row_number = pristine_permission.line_number
|
35
|
+
end
|
36
|
+
pristine_permission.operation = header_match.captures[1]
|
37
|
+
# parse the role and privilege set name
|
38
|
+
pristine_permission.privilege_set_name = parse_privilege_set_name(permission_line, line_number)
|
39
|
+
pristine_permission.pristine_role = parse_role(permission_line, line_number, use_db)
|
40
|
+
# it's pristine, so changes should be treated as such
|
41
|
+
# if a permission was created and later revoked, we should remove the pristine line which was created before
|
42
|
+
case pristine_permission.operation
|
43
|
+
when '+'
|
44
|
+
@permissions.push(pristine_permission)
|
45
|
+
when '-'
|
46
|
+
permission_to_delete = nil
|
47
|
+
#check if this is actually a permission that can be revoked.
|
48
|
+
@permissions.each do |known_permission|
|
49
|
+
if known_permission.privilege_set_name == pristine_permission.privilege_set_name and known_permission.pristine_role.name == pristine_permission.pristine_role.name
|
50
|
+
permission_to_delete = known_permission
|
51
|
+
break
|
52
|
+
end
|
53
|
+
end
|
54
|
+
if permission_to_delete.nil?
|
55
|
+
raise SyntaxError, "Error: trying to remove a privilege set with \"#{permission_line}\" on line #{(line_number + 1).to_s}, but this privilege set wasn't created!"
|
56
|
+
else
|
57
|
+
@permissions.push(pristine_permission)
|
58
|
+
end
|
59
|
+
when 'x', '=>'
|
60
|
+
raise NotImplementedError, "Using an x or => in a pristine file is not implemented yet"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def is_pristine_permission_line?(line, line_number)
|
66
|
+
if line.match(/^\s*(\d+)\s*:\s*([\+-x]|=>)\s*:(\s*[A-Za-z]+\(\s*[A-Za-z_]*\s*\))+\s*\Z/) #looks like pristine line.....
|
67
|
+
return true
|
68
|
+
end
|
69
|
+
if line.match(/^\s*(#.*|\s*)$/) # line is whitespace or comment line
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
raise SyntaxError, "Error: garbage found in input file on line #{(line_number + 1).to_s}" #line is rubbish
|
73
|
+
end
|
74
|
+
|
75
|
+
def parse_privilege_set_name(line, line_number)
|
76
|
+
if match_data= line.match(/^.*PrivilegeSet\(\s*([A-Za-z0-9_]+)\s*\)\s*/)
|
77
|
+
return match_data.captures[0]
|
78
|
+
end
|
79
|
+
raise SyntaxError, "Error: PrivilegeSet expected, but found: \"#{line}\" on line #{(line_number + 1).to_s}"
|
80
|
+
end
|
81
|
+
|
82
|
+
def parse_role(line, line_number, use_db = true)
|
83
|
+
raise NotImplementedError("Error: the AbstractPristineFile cannot parse roles, use a PristineFile or GenericPristineFile instead")
|
84
|
+
end
|
85
|
+
|
86
|
+
def permission_set
|
87
|
+
permission_set = Array.new(@permissions)
|
88
|
+
@permissions.each do |pristine_permission|
|
89
|
+
case pristine_permission.operation
|
90
|
+
when '+'
|
91
|
+
permission_set.push(pristine_permission)
|
92
|
+
when '-'
|
93
|
+
permission_to_delete = nil
|
94
|
+
#check if this is actually a permission that can be revoked.
|
95
|
+
permission_set.each do |known_permission|
|
96
|
+
if known_permission.privilege_set_name == pristine_permission.privilege_set_name and known_permission.pristine_role.name == pristine_permission.pristine_role.name and known_permission.operation == '+'
|
97
|
+
permission_to_delete = known_permission
|
98
|
+
break
|
99
|
+
end
|
100
|
+
end
|
101
|
+
if permission_to_delete.nil?
|
102
|
+
raise ArgumentError, "Error: trying to remove permission #{pristine_permission.privilege_set_name}\" for #{pristine_permission.pristine_role.name}, but this permission wasn't created!"
|
103
|
+
else
|
104
|
+
permission_set.delete(permission_to_delete)
|
105
|
+
permission_set.delete(pristine_permission)
|
106
|
+
end
|
107
|
+
when 'x', '=>'
|
108
|
+
raise NotImplementedError, "Using an x or => in a pristine file is not implemented yet"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
permission_set
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
class PristineFile < Cbac::CbacPristine::AbstractPristineFile
|
118
|
+
def parse_role(line, line_number, use_db = true)
|
119
|
+
if line.match(/^.*Admin\(\)/)
|
120
|
+
return @admin_role unless @admin_role.nil?
|
121
|
+
|
122
|
+
@admin_role = PristineRole.admin_role(use_db)
|
123
|
+
@generic_roles.push(@admin_role)
|
124
|
+
return @admin_role
|
125
|
+
end
|
126
|
+
if context_role_name = line.match(/^.*ContextRole\(\s*([A-Za-z0-9_]+)\s*\)/)
|
127
|
+
# NOTE: the 0 for an ID is very important! In CBAC a context role permission MUST have 0 as generic_role_id
|
128
|
+
# if not, the context role is not found by CBAC and thus will not work
|
129
|
+
context_role = use_db ? PristineRole.first(:conditions => {:role_type => PristineRole.ROLE_TYPES[:context], :name => context_role_name.captures[0]}) : nil
|
130
|
+
context_role = PristineRole.new(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:context], :name => context_role_name.captures[0]) if context_role.nil?
|
131
|
+
return context_role
|
132
|
+
end
|
133
|
+
raise SyntaxError, "Error: ContextRole or Admin expected, but found: \"#{line}\" on line #{(line_number + 1).to_s}"
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
class GenericPristineFile < Cbac::CbacPristine::AbstractPristineFile
|
140
|
+
def parse_role(line, line_number, use_db = true)
|
141
|
+
# generic pristine files differ, because they create generic roles when needed
|
142
|
+
# but those generic roles should be re-used if one with that name already exists
|
143
|
+
if generic_role= line.match(/^.*GenericRole\(\s*([A-Za-z0-9_]+)\s*\)/)
|
144
|
+
@generic_roles.each do |generic_cbac_role|
|
145
|
+
if generic_cbac_role.name == generic_role.captures[0]
|
146
|
+
return generic_cbac_role
|
147
|
+
end
|
148
|
+
end
|
149
|
+
role = use_db ? PristineRole.first(:conditions => {:role_type => PristineRole.ROLE_TYPES[:generic], :name => generic_role.captures[0]}) : nil
|
150
|
+
role = PristineRole.new(:role_id => @generic_roles.length + 2, :role_type => PristineRole.ROLE_TYPES[:generic], :name => generic_role.captures[0]) if role.nil?
|
151
|
+
@generic_roles.push(role)
|
152
|
+
return role
|
153
|
+
end
|
154
|
+
raise SyntaxError, "Error: GenericRole expected, but found: \"#{line}\" on line #{(line_number + 1).to_s}"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|