[Ovirt-devel] [PATCH server] first round of permissions refactoring.
Scott Seago
sseago at redhat.com
Mon Mar 30 19:08:33 UTC 2009
pulled out the roles and privileges from the ruby hashes embedded in permission.rb into separate DB tables. This allows the eventual creation of higher-level APIs to create custom roles, although for now the behavior of the system should be unchanged from before the patch.
Signed-off-by: Scott Seago <sseago at redhat.com>
---
src/app/controllers/hardware_controller.rb | 8 +-
src/app/controllers/permission_controller.rb | 3 +-
src/app/controllers/pool_controller.rb | 4 +-
src/app/controllers/resources_controller.rb | 2 +-
src/app/controllers/tree_controller.rb | 8 +-
src/app/controllers/vm_controller.rb | 14 +--
src/app/models/directory_pool.rb | 2 +-
src/app/models/permission.rb | 54 +--------
src/app/models/pool.rb | 54 ++++------
.../unit/task_test.rb => app/models/privilege.rb} | 31 ++----
src/{test/unit/task_test.rb => app/models/role.rb} | 32 ++----
src/app/models/smart_pool.rb | 2 +-
src/app/models/vm_task.rb | 18 ++--
src/app/views/permission/_form.rhtml | 2 +-
src/app/views/permission/_list.rhtml | 2 +-
src/app/views/user/_change_role_menu.rhtml | 4 +-
src/app/views/user/_grid.rhtml | 2 +-
src/app/views/user/_show.rhtml | 2 +-
src/db/migrate/037_add_roles_and_privileges.rb | 119 ++++++++++++++++++++
src/lib/tasks/vm-states-dot.rake | 1 +
src/script/grant_admin_privileges | 2 +-
src/test/fixtures/permissions.yml | 30 +++---
src/test/fixtures/privileges.yml | 10 ++
src/test/fixtures/roles.yml | 12 ++
src/test/functional/host_controller_test.rb | 2 +-
src/test/functional/nic_controller_test.rb | 2 +-
src/test/functional/permission_controller_test.rb | 8 +-
src/test/functional/quota_controller_test.rb | 6 +-
src/test/functional/resources_controller_test.rb | 2 +-
src/test/functional/storage_controller_test.rb | 9 +-
src/test/functional/vm_controller_test.rb | 10 +-
src/test/unit/active_record_env_test.rb | 4 +-
src/test/unit/permission_test.rb | 16 +--
src/test/unit/task_test.rb | 2 +-
34 files changed, 272 insertions(+), 207 deletions(-)
copy src/{test/unit/task_test.rb => app/models/privilege.rb} (50%)
copy src/{test/unit/task_test.rb => app/models/role.rb} (50%)
create mode 100644 src/db/migrate/037_add_roles_and_privileges.rb
create mode 100644 src/test/fixtures/privileges.yml
create mode 100644 src/test/fixtures/roles.yml
diff --git a/src/app/controllers/hardware_controller.rb b/src/app/controllers/hardware_controller.rb
index 3caf024..726e5bd 100644
--- a/src/app/controllers/hardware_controller.rb
+++ b/src/app/controllers/hardware_controller.rb
@@ -61,10 +61,10 @@ class HardwareController < PoolController
end
def json_view_tree
- json_tree_internal(Permission::PRIV_VIEW, :select_hardware_and_vm_pools)
+ json_tree_internal(Privilege::VIEW, :select_hardware_and_vm_pools)
end
def json_move_tree
- json_tree_internal(Permission::PRIV_MODIFY, :select_hardware_pools)
+ json_tree_internal(Privilege::MODIFY, :select_hardware_pools)
end
def json_tree_internal(privilege, filter_method)
id = params[:id]
@@ -81,7 +81,7 @@ class HardwareController < PoolController
pools = @pool.children
open_list = []
else
- pools = Pool.list_for_user(get_login_user,Permission::PRIV_VIEW)
+ pools = Pool.list_for_user(get_login_user,Privilege::VIEW)
hw_root = HardwarePool.get_default_pool
if !(pools.include?(hw_root))
if pools.include?(DirectoryPool.get_directory_root)
@@ -183,7 +183,7 @@ class HardwareController < PoolController
@resource_type = params[:resource_type]
@id = params[:id]
@pools = HardwarePool.get_default_pool.full_set_nested(:method => :json_hash_element,
- :privilege => Permission::PRIV_MODIFY, :user => get_login_user, :current_id => @id,
+ :privilege => Privilege::MODIFY, :user => get_login_user, :current_id => @id,
:type => :select_hardware_pools).to_json
render :layout => 'popup'
end
diff --git a/src/app/controllers/permission_controller.rb b/src/app/controllers/permission_controller.rb
index c301e1e..3bfbffa 100644
--- a/src/app/controllers/permission_controller.rb
+++ b/src/app/controllers/permission_controller.rb
@@ -42,6 +42,7 @@ class PermissionController < ApplicationController
@pool = Pool.find(params[:pool_id])
filter = @pool.permissions.collect{ |permission| permission.uid }
@users = Account.names(filter)
+ @roles = Role.find(:all).collect{ |role| [role.name, role.id] }
set_perms(@permission.pool)
# admin permission required to view permissions
unless @can_set_perms
@@ -74,7 +75,7 @@ class PermissionController < ApplicationController
#FIXME: we need permissions checks. user must have permission. We also need to fail
# for pools that aren't currently empty
def update_roles
- role = params[:user_role]
+ role = params[:role_id]
permission_ids_str = params[:permission_ids]
permission_ids = permission_ids_str.split(",").collect {|x| x.to_i}
diff --git a/src/app/controllers/pool_controller.rb b/src/app/controllers/pool_controller.rb
index 2809d6d..22cf1a4 100644
--- a/src/app/controllers/pool_controller.rb
+++ b/src/app/controllers/pool_controller.rb
@@ -57,14 +57,14 @@ class PoolController < ApplicationController
# resource's users list page
def show_users
- @roles = Permission::ROLES.keys
+ @roles = Role.find(:all).collect{ |role| [role.name, role.id] }
show
end
def users_json
attr_list = []
attr_list << :grid_id if params[:checkboxes]
- attr_list += [:uid, :user_role, :source]
+ attr_list += [:uid, [:role, :name], :source]
json_list(@pool.permissions, attr_list)
end
diff --git a/src/app/controllers/resources_controller.rb b/src/app/controllers/resources_controller.rb
index 7bed533..b57fae6 100644
--- a/src/app/controllers/resources_controller.rb
+++ b/src/app/controllers/resources_controller.rb
@@ -31,7 +31,7 @@ class ResourcesController < PoolController
def list
@user = get_login_user
- @vm_resource_pools = VmResourcePool.list_for_user(@user, Permission::PRIV_VIEW)
+ @vm_resource_pools = VmResourcePool.list_for_user(@user, Privilege::VIEW)
@vms = Set.new
@vm_resource_pools.each { |vm_resource_pool| @vms += vm_resource_pool.vms}
@vms = @vms.entries
diff --git a/src/app/controllers/tree_controller.rb b/src/app/controllers/tree_controller.rb
index b6e7404..365eaf0 100644
--- a/src/app/controllers/tree_controller.rb
+++ b/src/app/controllers/tree_controller.rb
@@ -2,9 +2,9 @@ class TreeController < ApplicationController
def get_pools
# TODO: split these into separate hash elements for HW and smart pools
pools = HardwarePool.get_default_pool.full_set_nested(:method => :json_hash_element,
- :privilege => Permission::PRIV_VIEW, :user => get_login_user)
+ :privilege => Privilege::VIEW, :user => get_login_user)
pools += DirectoryPool.get_smart_root.full_set_nested(:method => :json_hash_element,
- :privilege => Permission::PRIV_VIEW, :user => get_login_user,
+ :privilege => Privilege::VIEW, :user => get_login_user,
:smart_pool_set => true)
end
@@ -32,13 +32,13 @@ class TreeController < ApplicationController
pools = build_json(
HardwarePool.get_default_pool.full_set_nested(
:method => :json_hash_element,
- :privilege => Permission::PRIV_VIEW,
+ :privilege => Privilege::VIEW,
:user => get_login_user))
smart_pools = adjust_smart_pool_list(
build_json(
DirectoryPool.get_smart_root.full_set_nested(
:method => :json_hash_element,
- :privilege => Permission::PRIV_VIEW,
+ :privilege => Privilege::VIEW,
:user => get_login_user,
:smart_pool_set => true)))
@serverHash = {:pools => smart_pools + pools }
diff --git a/src/app/controllers/vm_controller.rb b/src/app/controllers/vm_controller.rb
index aa575c6..a81f6b5 100644
--- a/src/app/controllers/vm_controller.rb
+++ b/src/app/controllers/vm_controller.rb
@@ -26,14 +26,12 @@ class VmController < ApplicationController
before_filter :pre_vm_action, :only => [:vm_action, :cancel_queued_tasks, :console]
def index
- roles = "('" +
- Permission::roles_for_privilege(Permission::PRIV_VIEW).join("', '") +
- "')"
- user = get_login_user
- @vms = Vm.find(:all,
- :joins => "join permissions p on (vm_resource_pool_id = p.pool_id)",
- :conditions => [ "p.uid = :user and p.user_role in #{roles}",
- { :user => user }])
+ @vms = Vm.find(:all,
+ :include => [{:vm_resource_pool =>
+ {:permissions => {:role => :privileges}}}],
+ :conditions => ["privileges.name=:priv
+ and permissions.uid=:user",
+ { :user => get_login_user, :priv => Privilege::VIEW }])
respond_to do |format|
format.xml { render :xml => @vms.to_xml(:include => :host) }
end
diff --git a/src/app/models/directory_pool.rb b/src/app/models/directory_pool.rb
index 82486af..91645c1 100644
--- a/src/app/models/directory_pool.rb
+++ b/src/app/models/directory_pool.rb
@@ -50,7 +50,7 @@ class DirectoryPool < Pool
user_root.create_with_parent(get_smart_root)
permission = Permission.new({:pool_id => user_root.id,
:uid => user,
- :user_role => Permission::ROLE_SUPER_ADMIN})
+ :role_id => Role.find_by_name(Role::SUPER_ADMIN).id})
#we don't need save_with_new_children here since there are no children yet
permission.save!
end
diff --git a/src/app/models/permission.rb b/src/app/models/permission.rb
index b3929ad..2567b08 100644
--- a/src/app/models/permission.rb
+++ b/src/app/models/permission.rb
@@ -24,62 +24,20 @@ class Permission < ActiveRecord::Base
has_many :child_permissions, :dependent => :destroy,
:class_name => "Permission", :foreign_key => "inherited_from_id"
+ belongs_to :role
+
validates_presence_of :pool_id
+ validates_presence_of :role_id
validates_presence_of :uid
validates_uniqueness_of :uid, :scope => [:pool_id, :inherited_from_id]
-
- ROLE_SUPER_ADMIN = "Super Admin"
- ROLE_ADMIN = "Administrator"
- ROLE_USER = "User"
- ROLE_MONITOR = "Monitor"
-
- PRIV_PERM_SET = "set_perms"
- PRIV_PERM_VIEW = "view_perms"
- PRIV_MODIFY = "modify"
- PRIV_VM_CONTROL = "vm_control"
- PRIV_VIEW = "view"
-
- ROLES = { ROLE_SUPER_ADMIN => [PRIV_VIEW, PRIV_VM_CONTROL, PRIV_MODIFY,
- PRIV_PERM_VIEW, PRIV_PERM_SET],
- ROLE_ADMIN => [PRIV_VIEW, PRIV_VM_CONTROL, PRIV_MODIFY],
- ROLE_USER => [PRIV_VIEW, PRIV_VM_CONTROL],
- ROLE_MONITOR => [PRIV_VIEW]}
-
-
- validates_inclusion_of :user_role,
- :in => ROLES.keys
-
- def self.invert_roles
- return_hash = {}
- ROLES.each do |role, privs|
- privs.each do |priv|
- priv_key = return_hash[priv]
- priv_key ||= []
- priv_key << role
- return_hash[priv] = priv_key
- end
- end
- return_hash
- end
-
def name
@account ||= Account.find("uid=#{uid}")
@account.cn
end
- PRIVILEGES = self.invert_roles
-
- def self.privileges_for_role(role)
- ROLES[role]
- end
-
- def self.roles_for_privilege(privilege)
- PRIVILEGES[privilege]
- end
-
def is_primary?
inherited_from_id.nil?
end
@@ -94,10 +52,10 @@ class Permission < ActiveRecord::Base
end
def update_role(new_role)
self.transaction do
- self.user_role = new_role
+ self.role_id = new_role
self.save!
child_permissions.each do |permission|
- permission.user_role = new_role
+ permission.role_id = new_role
permission.save!
end
end
@@ -108,7 +66,7 @@ class Permission < ActiveRecord::Base
pool.all_children.each do |subpool|
new_permission = Permission.new({:pool_id => subpool.id,
:uid => uid,
- :user_role => user_role,
+ :role_id => role_id,
:inherited_from_id => id})
new_permission.save!
end
diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb
index 372cf54..6f2a086 100644
--- a/src/app/models/pool.rb
+++ b/src/app/models/pool.rb
@@ -23,7 +23,7 @@ class Pool < ActiveRecord::Base
has_many :membership_audit_events, :as => :container_target, :dependent => :destroy
# moved associations here so that nested set :include directives work
# TODO: find a way to put this back into vm_resource_pool.rb
- has_many :vms, :dependent => :nullify, :order => "id ASC", :foreign_key => :vm_resource_pool_id
+ has_many :vms, :dependent => :nullify, :order => "vms.id ASC", :foreign_key => :vm_resource_pool_id
# TODO: find a way to put this back into hardware_pool.rb
has_many :hosts, :include => :nics, :dependent => :nullify, :order => "hosts.id ASC", :foreign_key => "hardware_pool_id" do
def total_cpus
@@ -37,7 +37,7 @@ class Pool < ActiveRecord::Base
end
end
- has_many :storage_pools, :dependent => :nullify, :order => "id ASC", :foreign_key => 'hardware_pool_id' do
+ has_many :storage_pools, :dependent => :nullify, :order => "storage_pools.id ASC", :foreign_key => 'hardware_pool_id' do
def total_size_in_gb
find(:all).inject(0){ |sum, sp| sum + sp.storage_volumes.total_size_in_gb }
end
@@ -57,20 +57,7 @@ class Pool < ActiveRecord::Base
:in => %w( DirectoryPool HardwarePool VmResourcePool SmartPool )
# overloading this method such that we can use permissions.admins to get all the admins for an object
- has_many :permissions, :dependent => :destroy, :order => "id ASC" do
- def super_admins
- find_all_by_user_role(Permission::ROLE_SUPER_ADMIN)
- end
- def admins
- find_all_by_user_role(Permission::ROLE_ADMIN)
- end
- def users
- find_all_by_user_role(Permission::ROLE_USER)
- end
- def monitors
- find_all_by_user_role(Permission::ROLE_MONITOR)
- end
- end
+ has_many :permissions, :dependent => :destroy, :include => :role, :order => "permissions.id ASC"
has_one :quota, :dependent => :destroy
@@ -81,7 +68,7 @@ class Pool < ActiveRecord::Base
parent.permissions.each do |permission|
new_permission = Permission.new({:pool_id => id,
:uid => permission.uid,
- :user_role => permission.user_role,
+ :role_id => permission.role_id,
:inherited_from_id =>
permission.inherited_from_id.nil? ?
permission.id :
@@ -104,10 +91,10 @@ class Pool < ActiveRecord::Base
else
inherited_clause = "and permissions.inherited_from_id is null"
end
- pools = find(:all, :include => "permissions",
- :conditions => "permissions.uid='#{user}' #{inherited_clause} and
- permissions.user_role in
- ('#{Permission.roles_for_privilege(privilege).join("', '")}')")
+ pools = find(:all, :include => [{:permissions => {:role => :privileges}}],
+ :conditions => ["permissions.uid=:user #{inherited_clause} and
+ privileges.name=:priv",
+ { :user => user, :priv => privilege }])
end
def self.select_hardware_pools(pools)
@@ -142,26 +129,26 @@ class Pool < ActiveRecord::Base
end
def can_view(user)
- has_privilege(user, Permission::PRIV_VIEW)
+ has_privilege(user, Privilege::VIEW)
end
def can_control_vms(user)
- has_privilege(user, Permission::PRIV_VM_CONTROL)
+ has_privilege(user, Privilege::VM_CONTROL)
end
def can_modify(user)
- has_privilege(user, Permission::PRIV_MODIFY)
+ has_privilege(user, Privilege::MODIFY)
end
def can_view_perms(user)
- has_privilege(user, Permission::PRIV_PERM_VIEW)
+ has_privilege(user, Privilege::PERM_VIEW)
end
def can_set_perms(user)
- has_privilege(user, Permission::PRIV_PERM_SET)
+ has_privilege(user, Privilege::PERM_SET)
end
def has_privilege(user, privilege)
- permissions.find(:first,
- :conditions => "permissions.uid='#{user}' and
- permissions.user_role in
- ('#{Permission.roles_for_privilege(privilege).join("', '")}')")
+ permissions.find(:first, :include => [:role => :privileges],
+ :conditions => ["permissions.uid=:user and
+ privileges.name=:priv",
+ { :user => user, :priv => privilege }])
end
def total_resources
@@ -239,10 +226,9 @@ class Pool < ActiveRecord::Base
type = opts.delete(:type)
smart_pool_set = opts.delete(:smart_pool_set)
if privilege and user
- opts[:include] = "permissions"
- opts[:conditions] = "permissions.uid='#{user}' and
- permissions.user_role in
- ('#{Permission.roles_for_privilege(privilege).join("', '")}')"
+ opts[:include] = [{:permissions => {:role => :privileges}}]
+ opts[:conditions] = ["permissions.uid=:user and privileges.name=:priv",
+ { :user => user, :priv => privilege }]
end
current_id = opts.delete(:current_id)
opts.delete(:order)
diff --git a/src/test/unit/task_test.rb b/src/app/models/privilege.rb
similarity index 50%
copy from src/test/unit/task_test.rb
copy to src/app/models/privilege.rb
index ba780e7..7a30b8f 100644
--- a/src/test/unit/task_test.rb
+++ b/src/app/models/privilege.rb
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2008 Red Hat, Inc.
+# Copyright (C) 2009 Red Hat, Inc.
# Written by Scott Seago <sseago at redhat.com>
#
# This program is free software; you can redistribute it and/or modify
@@ -17,28 +17,19 @@
# MA 02110-1301, USA. A copy of the GNU General Public License is
# also available at http://www.gnu.org/copyleft/gpl.html.
-require File.dirname(__FILE__) + '/../test_helper'
+class Privilege < ActiveRecord::Base
+ has_and_belongs_to_many :roles
-class TaskTest < Test::Unit::TestCase
- fixtures :pools, :hosts, :vms, :permissions, :tasks
+ validates_presence_of :name
+ validates_uniqueness_of :name
- def setup
- @task = Task.new( :type => 'HostTask', :state => 'finished' )
- end
- def test_valid_fails_with_bad_type
- @task.type = 'foobar'
- flunk 'Task must specify valid type' if @task.valid?
- end
+ #default privileges
+ PERM_SET = "set_perms"
+ PERM_VIEW = "view_perms"
+ MODIFY = "modify"
+ VM_CONTROL = "vm_control"
+ VIEW = "view"
- def test_valid_fails_with_bad_state
- @task.state = 'foobar'
- flunk 'Task must specify valid state' if @task.valid?
- end
-
- def test_exercise_task_relationships
- assert_equal tasks(:shutdown_production_httpd_appliance_task).task_target.vm_resource_pool.name, 'corp.com production vmpool'
- assert_equal tasks(:shutdown_production_httpd_appliance_task).task_target.host.hostname, 'prod.corp.com'
- end
end
diff --git a/src/test/unit/task_test.rb b/src/app/models/role.rb
similarity index 50%
copy from src/test/unit/task_test.rb
copy to src/app/models/role.rb
index ba780e7..969fbbe 100644
--- a/src/test/unit/task_test.rb
+++ b/src/app/models/role.rb
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2008 Red Hat, Inc.
+# Copyright (C) 2009 Red Hat, Inc.
# Written by Scott Seago <sseago at redhat.com>
#
# This program is free software; you can redistribute it and/or modify
@@ -17,28 +17,18 @@
# MA 02110-1301, USA. A copy of the GNU General Public License is
# also available at http://www.gnu.org/copyleft/gpl.html.
-require File.dirname(__FILE__) + '/../test_helper'
+class Role < ActiveRecord::Base
+ has_many :permissions
+ has_and_belongs_to_many :privileges
-class TaskTest < Test::Unit::TestCase
- fixtures :pools, :hosts, :vms, :permissions, :tasks
+ validates_presence_of :name
+ validates_uniqueness_of :name
- def setup
- @task = Task.new( :type => 'HostTask', :state => 'finished' )
- end
- def test_valid_fails_with_bad_type
- @task.type = 'foobar'
- flunk 'Task must specify valid type' if @task.valid?
- end
-
- def test_valid_fails_with_bad_state
- @task.state = 'foobar'
- flunk 'Task must specify valid state' if @task.valid?
- end
-
- def test_exercise_task_relationships
- assert_equal tasks(:shutdown_production_httpd_appliance_task).task_target.vm_resource_pool.name, 'corp.com production vmpool'
- assert_equal tasks(:shutdown_production_httpd_appliance_task).task_target.host.hostname, 'prod.corp.com'
- end
+ #default roles
+ SUPER_ADMIN = "Super Admin"
+ ADMIN = "Administrator"
+ USER = "User"
+ MONITOR = "Monitor"
end
diff --git a/src/app/models/smart_pool.rb b/src/app/models/smart_pool.rb
index ca55a2e..dba000d 100644
--- a/src/app/models/smart_pool.rb
+++ b/src/app/models/smart_pool.rb
@@ -74,7 +74,7 @@ class SmartPool < Pool
def self.smart_pools_for_user(user)
nested_pools = DirectoryPool.get_smart_root.full_set_nested(
- :privilege => Permission::PRIV_MODIFY, :user => user,
+ :privilege => Privilege::MODIFY, :user => user,
:smart_pool_set => true)[0][:children]
user_pools = []
other_pools = []
diff --git a/src/app/models/vm_task.rb b/src/app/models/vm_task.rb
index 27513bb..ed33564 100644
--- a/src/app/models/vm_task.rb
+++ b/src/app/models/vm_task.rb
@@ -47,7 +47,7 @@ class VmTask < Task
:running => Vm::STATE_CREATING,
:success => Vm::STATE_STOPPED,
:failure => Vm::STATE_CREATE_FAILED,
- :privilege => [Permission::PRIV_MODIFY,
+ :privilege => [Privilege::MODIFY,
PRIV_OBJECT_VM_POOL]},
ACTION_START_VM => { :label => "Start",
:icon => "icon_start.png",
@@ -55,7 +55,7 @@ class VmTask < Task
:running => Vm::STATE_STARTING,
:success => Vm::STATE_RUNNING,
:failure => Vm::STATE_STOPPED,
- :privilege => [Permission::PRIV_VM_CONTROL,
+ :privilege => [Privilege::VM_CONTROL,
PRIV_OBJECT_VM_POOL]},
ACTION_SHUTDOWN_VM => { :label => "Shutdown",
:icon => "icon_x.png",
@@ -63,7 +63,7 @@ class VmTask < Task
:running => Vm::STATE_STOPPING,
:success => Vm::STATE_STOPPED,
:failure => Vm::STATE_RUNNING,
- :privilege => [Permission::PRIV_VM_CONTROL,
+ :privilege => [Privilege::VM_CONTROL,
PRIV_OBJECT_VM_POOL]},
ACTION_POWEROFF_VM => { :label => "Poweroff",
:icon => "icon_x.png",
@@ -71,7 +71,7 @@ class VmTask < Task
:running => Vm::STATE_POWERING_OFF,
:success => Vm::STATE_STOPPED,
:failure => Vm::STATE_RUNNING,
- :privilege => [Permission::PRIV_VM_CONTROL,
+ :privilege => [Privilege::VM_CONTROL,
PRIV_OBJECT_VM_POOL]},
ACTION_SUSPEND_VM => { :label => "Suspend",
:icon => "icon_suspend.png",
@@ -79,7 +79,7 @@ class VmTask < Task
:running => Vm::STATE_SUSPENDING,
:success => Vm::STATE_SUSPENDED,
:failure => Vm::STATE_RUNNING,
- :privilege => [Permission::PRIV_VM_CONTROL,
+ :privilege => [Privilege::VM_CONTROL,
PRIV_OBJECT_VM_POOL]},
ACTION_RESUME_VM => { :label => "Resume",
:icon => "icon_start.png",
@@ -87,7 +87,7 @@ class VmTask < Task
:running => Vm::STATE_RESUMING,
:success => Vm::STATE_RUNNING,
:failure => Vm::STATE_SUSPENDED,
- :privilege => [Permission::PRIV_VM_CONTROL,
+ :privilege => [Privilege::VM_CONTROL,
PRIV_OBJECT_VM_POOL]},
ACTION_SAVE_VM => { :label => "Save",
:icon => "icon_save.png",
@@ -95,7 +95,7 @@ class VmTask < Task
:running => Vm::STATE_SAVING,
:success => Vm::STATE_SAVED,
:failure => Vm::STATE_RUNNING,
- :privilege => [Permission::PRIV_VM_CONTROL,
+ :privilege => [Privilege::VM_CONTROL,
PRIV_OBJECT_VM_POOL]},
ACTION_RESTORE_VM => { :label => "Restore",
:icon => "icon_restore.png",
@@ -103,7 +103,7 @@ class VmTask < Task
:running => Vm::STATE_RESTORING,
:success => Vm::STATE_RUNNING,
:failure => Vm::STATE_SAVED,
- :privilege => [Permission::PRIV_VM_CONTROL,
+ :privilege => [Privilege::VM_CONTROL,
PRIV_OBJECT_VM_POOL]},
ACTION_MIGRATE_VM => { :label => "Migrate",
:icon => "icon_restore.png",
@@ -111,7 +111,7 @@ class VmTask < Task
:running => Vm::STATE_MIGRATING,
:success => Vm::STATE_RUNNING,
:failure => Vm::STATE_RUNNING,
- :privilege => [Permission::PRIV_MODIFY,
+ :privilege => [Privilege::MODIFY,
PRIV_OBJECT_HW_POOL],
:popup_action => 'migrate'} }
diff --git a/src/app/views/permission/_form.rhtml b/src/app/views/permission/_form.rhtml
index 2a1e93c..89d4e03 100644
--- a/src/app/views/permission/_form.rhtml
+++ b/src/app/views/permission/_form.rhtml
@@ -3,7 +3,7 @@
<!--[form:permission]-->
<%= hidden_field_with_label "Pool", 'permission', 'pool_id', @permission.pool.name %>
-<%= select_with_label 'Role', 'permission', 'user_role', Permission::ROLES.keys %>
+<%= select_with_label 'Role', 'permission', 'role_id', @roles %>
<%= select_with_label 'User', 'permission', 'uid', @users %>
diff --git a/src/app/views/permission/_list.rhtml b/src/app/views/permission/_list.rhtml
index 57613cb..713f193 100644
--- a/src/app/views/permission/_list.rhtml
+++ b/src/app/views/permission/_list.rhtml
@@ -12,7 +12,7 @@
<% for permission in permissions %>
<tr class="<%= cycle('odd','even') %>">
<td><%= permission.uid %>
- <td><%= permission.user_role %>
+ <td><%= permission.role.name %>
<%if show_object -%>
<td style="text-align:left;">
<%= link_to permission.pool.name,
diff --git a/src/app/views/user/_change_role_menu.rhtml b/src/app/views/user/_change_role_menu.rhtml
index f35cd3b..4044b88 100644
--- a/src/app/views/user/_change_role_menu.rhtml
+++ b/src/app/views/user/_change_role_menu.rhtml
@@ -1,12 +1,12 @@
<%= image_tag "icon_move.png", :style => "vertical-align:middle;" %> Change Role <%= image_tag "icon_toolbar_arrow.gif", :style => "vertical-align:middle;" %>
<ul>
<% @roles.each_index { |index| %>
- <li onClick="update_users('<%=@roles[index]%>')"
+ <li onClick="update_users('<%=@roles[index][1]%>')"
<% if index == @roles.length - 1 %>
style="border-bottom: 1px solid black;"
<% end %>
>
- <%=@roles[index]%>
+ <%=@roles[index][0]%>
</li>
<% } %>
</ul>
diff --git a/src/app/views/user/_grid.rhtml b/src/app/views/user/_grid.rhtml
index 8f7b4cf..10a10c8 100644
--- a/src/app/views/user/_grid.rhtml
+++ b/src/app/views/user/_grid.rhtml
@@ -16,7 +16,7 @@
colModel : [
<%= "{display: '', width : 20, align: 'left', process: #{table_id}checkbox}," if checkboxes %>
{display: 'Name', name : 'uid', width : 180, sortable : true, align: 'left'},
- {display: 'Role', name : 'user_role', width : 80, sortable : true, align: 'left'},
+ {display: 'Role', name : 'roles.name', width : 80, sortable : true, align: 'left'},
{display: '', width : 80, sortable : true, align: 'left'}
],
sortname: "user",
diff --git a/src/app/views/user/_show.rhtml b/src/app/views/user/_show.rhtml
index 8ea423e..c7c8008 100644
--- a/src/app/views/user/_show.rhtml
+++ b/src/app/views/user/_show.rhtml
@@ -31,7 +31,7 @@
var permissions = get_selected_users();
if (validate_selected(permissions, "users")) {
$.post('<%= url_for :controller => "permission", :action => "update_roles" %>',
- { permission_ids: permissions.toString(), user_role: role },
+ { permission_ids: permissions.toString(), role_id: role },
function(data,status){
$tabs.tabs("load",$tabs.data('selected.tabs'));
if (data.alert) {
diff --git a/src/db/migrate/037_add_roles_and_privileges.rb b/src/db/migrate/037_add_roles_and_privileges.rb
new file mode 100644
index 0000000..322014e
--- /dev/null
+++ b/src/db/migrate/037_add_roles_and_privileges.rb
@@ -0,0 +1,119 @@
+#
+# Copyright (C) 2009 Red Hat, Inc.
+# Written by Scott Seago <sseago at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+class AddRolesAndPrivileges < ActiveRecord::Migration
+ def self.up
+# create_table :permissions do |t|
+# t.string :user_role
+# t.string :user
+# t.integer :pool_id
+# t.integer :inherited_from_id
+# t.integer :lock_version, :default => 0
+# end
+ create_table :roles do |t|
+ t.string :name
+ t.integer :lock_version, :default => 0
+ end
+ create_table :privileges do |t|
+ t.string :name
+ t.integer :lock_version, :default => 0
+ end
+
+ create_table :privileges_roles, :id => false do |t|
+ t.integer :privilege_id, :null => false
+ t.integer :role_id, :null => false
+ end
+ execute "alter table privileges_roles add constraint
+ fk_priv_roles_role_id
+ foreign key (role_id) references roles(id)"
+ execute "alter table privileges_roles add constraint
+ fk_priv_roles_priv_id
+ foreign key (privilege_id) references privileges(id)"
+
+ add_column :permissions, :role_id, :integer
+ execute "alter table permissions add constraint fk_perm_roles
+ foreign key (role_id) references roles(id)"
+
+ #create default roles and privileges
+ Role.transaction do
+ role_super_admin = Role.new({:name => "Super Admin"})
+ role_super_admin.save!
+ role_admin = Role.new({:name => "Administrator"})
+ role_admin.save!
+ role_user = Role.new({:name => "User"})
+ role_user.save!
+ role_monitor = Role.new({:name => "Monitor"})
+ role_monitor.save!
+
+ priv_perm_set = Privilege.new({:name => "set_perms"})
+ priv_perm_set.save!
+ priv_perm_view = Privilege.new({:name => "view_perms"})
+ priv_perm_view.save!
+ priv_modify = Privilege.new({:name => "modify"})
+ priv_modify.save!
+ priv_vm_control = Privilege.new({:name => "vm_control"})
+ priv_vm_control.save!
+ priv_view = Privilege.new({:name => "view"})
+ priv_view.save!
+
+ role_super_admin.privileges = [priv_view, priv_vm_control, priv_modify,
+ priv_perm_view, priv_perm_set]
+ role_super_admin.save!
+ role_admin.privileges = [priv_view, priv_vm_control, priv_modify]
+ role_admin.save!
+ role_user.privileges = [priv_view, priv_vm_control]
+ role_user.save!
+ role_monitor.privileges = [priv_view]
+ role_monitor.save!
+ Permission.find(:all).each do |permission|
+ permission.role = case permission.user_role
+ when "Super Admin"; role_super_admin
+ when "Administrator"; role_admin
+ when "User"; role_user
+ when "Monitor"; role_monitor
+ else nil
+ end
+ permission.save
+ end
+ end
+ remove_column :permissions, :user_role
+
+ end
+
+
+ def self.down
+ add_column :permissions, :user_role, :string
+ Permission.transaction do
+ Permission.find(:all).each do |permission|
+ case permission.role.name
+ when ["Super Admin", "Administrator", "User", "Monitor"]
+ permission.user_role = permission.role.name
+ permission.save
+ else
+ permission.destroy
+ end
+ end
+ end
+ remove_column :permissions, :role_id
+
+ drop_table :privileges_roles
+ drop_table :privileges
+ drop_table :roles
+ end
+end
diff --git a/src/lib/tasks/vm-states-dot.rake b/src/lib/tasks/vm-states-dot.rake
index 74f1f8e..c26f00e 100644
--- a/src/lib/tasks/vm-states-dot.rake
+++ b/src/lib/tasks/vm-states-dot.rake
@@ -1,5 +1,6 @@
# -*- ruby -*-
require 'permission'
+require 'privilege'
require 'task'
require 'vm'
require 'vm_task'
diff --git a/src/script/grant_admin_privileges b/src/script/grant_admin_privileges
index 4cafa74..231b1f8 100755
--- a/src/script/grant_admin_privileges
+++ b/src/script/grant_admin_privileges
@@ -14,7 +14,7 @@ ActiveLdap::Base.establish_connection :base => base, :host => host, :try_sasl =>
if Account.exists?("uid=#{uid}")
puts "Creating an admin account for #{uid}..."
$pool = DirectoryPool.get_directory_root
- permission = Permission.new(:user_role => Permission::ROLE_SUPER_ADMIN,
+ permission = Permission.new(:user_role => Role.find_by_name(Role::SUPER_ADMIN).id,
:uid => uid,
:pool_id => $pool.id)
permission.save_with_new_children
diff --git a/src/test/fixtures/permissions.yml b/src/test/fixtures/permissions.yml
index 4fff79e..4895f3e 100644
--- a/src/test/fixtures/permissions.yml
+++ b/src/test/fixtures/permissions.yml
@@ -1,39 +1,39 @@
ovirtadmin_root:
- user_role: Super Admin
+ role: super_admin
uid: ovirtadmin
pool: root_dir_pool
ovirtadmin_default:
- user_role: Super Admin
+ role: super_admin
uid: ovirtadmin
pool: default
- inherited_from_id: <%= Fixtures.identify(:ovirtadmin_root) %>
+ parent_permission: ovirtadmin_root
ovirtadmin_hardware_pool:
- user_role: Super Admin
+ role: super_admin
uid: ovirtadmin
pool: hw_dir_pool
- inherited_from_id: <%= Fixtures.identify(:ovirtadmin_root) %>
+ parent_permission: ovirtadmin_root
ovirtadmin_users_pool:
- user_role: Super Admin
+ role: super_admin
uid: ovirtadmin
pool: smart_dir_pool
- inherited_from_id: <%= Fixtures.identify(:ovirtadmin_root) %>
+ parent_permission: ovirtadmin_root
ovirtadmin_corp_com_pool:
- user_role: Super Admin
+ role: super_admin
uid: ovirtadmin
pool: corp_com
- inherited_from_id: <%= Fixtures.identify(:ovirtadmin_root) %>
+ parent_permission: ovirtadmin_root
ovirtadmin_corp_com_production_vmpool:
- user_role: Super Admin
+ role: super_admin
uid: ovirtadmin
pool: corp_com_production_vmpool
- inherited_from_id: <%= Fixtures.identify(:ovirtadmin_root) %>
+ parent_permission: ovirtadmin_root
ovirtadmin_prodops_pool:
- user_role: Super Admin #Monitor
+ role: super_admin
uid: ovirtadmin
pool: corp_com_prod
- inherited_from_id: <%= Fixtures.identify(:ovirtadmin_root) %>
+ parent_permission: ovirtadmin_root
ovirtadmin_corp_com_qa_pool:
- user_role: Monitor
+ role: monitor
uid: ovirtadmin
pool: corp_com_qa
- inherited_from_id: <%= Fixtures.identify(:ovirtadmin_root) %>
\ No newline at end of file
+ parent_permission: ovirtadmin_root
diff --git a/src/test/fixtures/privileges.yml b/src/test/fixtures/privileges.yml
new file mode 100644
index 0000000..3f19584
--- /dev/null
+++ b/src/test/fixtures/privileges.yml
@@ -0,0 +1,10 @@
+set_perms:
+ name: set_perms
+view_perms:
+ name: view_perms
+modify:
+ name: modify
+vm_control:
+ name: vm_control
+view:
+ name: view
diff --git a/src/test/fixtures/roles.yml b/src/test/fixtures/roles.yml
new file mode 100644
index 0000000..774158d
--- /dev/null
+++ b/src/test/fixtures/roles.yml
@@ -0,0 +1,12 @@
+super_admin:
+ name: Super Admin
+ privileges: view, vm_control, modify, view_perms, set_perms
+administrator:
+ name: Administrator
+ privileges: view, vm_control, modify
+user:
+ name: User
+ privileges: view, vm_control
+monitor:
+ name: Monitor
+ privileges: view
diff --git a/src/test/functional/host_controller_test.rb b/src/test/functional/host_controller_test.rb
index 9a97009..497fe5a 100644
--- a/src/test/functional/host_controller_test.rb
+++ b/src/test/functional/host_controller_test.rb
@@ -24,7 +24,7 @@ require 'host_controller'
class HostController; def rescue_action(e) raise e end; end
class HostControllerTest < Test::Unit::TestCase
- fixtures :hosts, :pools, :permissions
+ fixtures :hosts, :pools, :privileges, :roles, :permissions
def setup
@controller = HostController.new
diff --git a/src/test/functional/nic_controller_test.rb b/src/test/functional/nic_controller_test.rb
index 8a8776a..68ea3f9 100644
--- a/src/test/functional/nic_controller_test.rb
+++ b/src/test/functional/nic_controller_test.rb
@@ -24,7 +24,7 @@ require 'nic_controller'
class NicController; def rescue_action(e) raise e end; end
class NicControllerTest < Test::Unit::TestCase
- fixtures :permissions, :pools, :nics
+ fixtures :privileges, :roles, :permissions, :pools, :nics
def setup
@controller = NicController.new
diff --git a/src/test/functional/permission_controller_test.rb b/src/test/functional/permission_controller_test.rb
index c32100a..f5aa4a9 100644
--- a/src/test/functional/permission_controller_test.rb
+++ b/src/test/functional/permission_controller_test.rb
@@ -24,7 +24,7 @@ require 'permission_controller'
class PermissionController; def rescue_action(e) raise e end; end
class PermissionControllerTest < Test::Unit::TestCase
- fixtures :permissions, :pools
+ fixtures :privileges, :roles, :permissions, :pools
def setup
@controller = PermissionController.new
@@ -55,9 +55,9 @@ class PermissionControllerTest < Test::Unit::TestCase
def test_create
num_permissions = Permission.count
- post :create, :permission => { :user_role => 'Administrator',
- :uid => 'admin',
- :pool_id => pools(:corp_com_production_vmpool).id}
+ post :create, :permission => { :role_id => roles(:administrator).id,
+ :uid => 'admin',
+ :pool_id => pools(:corp_com_production_vmpool).id}
assert_response :success
assert_equal num_permissions + 1, Permission.count
end
diff --git a/src/test/functional/quota_controller_test.rb b/src/test/functional/quota_controller_test.rb
index dd44dfc..b8f78e6 100644
--- a/src/test/functional/quota_controller_test.rb
+++ b/src/test/functional/quota_controller_test.rb
@@ -90,8 +90,10 @@ class QuotaControllerTest < Test::Unit::TestCase
end
def test_no_perms_to_destroy
- post :destroy, :id => quotas(:corp_com_dev_quota).id
- assert_response :redirect #Is this really what we want? Or should we just pop up the login page?
+ post :destroy, :id => quotas(:corp_com_dev_quota).id, :format => "json"
+ assert_response :success
+ json = ActiveSupport::JSON.decode(@response.body)
+ assert_equal 'You do not have permission to create or modify this item ', json['alert']
end
#FIXME: write the code to make this a real test!
diff --git a/src/test/functional/resources_controller_test.rb b/src/test/functional/resources_controller_test.rb
index 0312c0c..976e2d1 100644
--- a/src/test/functional/resources_controller_test.rb
+++ b/src/test/functional/resources_controller_test.rb
@@ -24,7 +24,7 @@ require 'resources_controller'
class ResourcesController; def rescue_action(e) raise e end; end
class ResourcesControllerTest < ActionController::TestCase
- fixtures :permissions, :pools
+ fixtures :privileges, :roles, :permissions, :pools
def setup
@controller = ResourcesController.new
diff --git a/src/test/functional/storage_controller_test.rb b/src/test/functional/storage_controller_test.rb
index f08fe1b..66326d9 100644
--- a/src/test/functional/storage_controller_test.rb
+++ b/src/test/functional/storage_controller_test.rb
@@ -24,7 +24,8 @@ require 'storage_controller'
class StorageController; def rescue_action(e) raise e end; end
class StorageControllerTest < Test::Unit::TestCase
- fixtures :permissions, :pools, :storage_volumes, :storage_pools
+ fixtures :privileges, :roles, :permissions, :pools,
+ :storage_volumes, :storage_pools
def setup
@controller = StorageController.new
@@ -103,8 +104,10 @@ class StorageControllerTest < Test::Unit::TestCase
end
def test_no_perms_to_destroy
- post :destroy, :id => storage_pools(:corp_com_dev_nfs_ovirtnfs).id
- assert_response :redirect #Is this really what we want? Or should we just pop up the login page?
+ xml_http_request :post, :destroy, :id => storage_pools(:corp_com_dev_nfs_ovirtnfs).id, :format => "json"
+ assert_response :success
+ json = ActiveSupport::JSON.decode(@response.body)
+ assert_equal 'You do not have permission to create or modify this item ', json['alert']
end
#FIXME: write the code to make this a real test!
diff --git a/src/test/functional/vm_controller_test.rb b/src/test/functional/vm_controller_test.rb
index 7936f01..c7769dd 100644
--- a/src/test/functional/vm_controller_test.rb
+++ b/src/test/functional/vm_controller_test.rb
@@ -24,7 +24,7 @@ require 'vm_controller'
class VmController; def rescue_action(e) raise e end; end
class VmControllerTest < Test::Unit::TestCase
- fixtures :permissions, :pools, :vms
+ fixtures :privileges, :roles, :permissions, :pools, :vms
def setup
@controller = VmController.new
@@ -46,11 +46,9 @@ class VmControllerTest < Test::Unit::TestCase
end
def test_new
- get :new, :hardware_pool_id => @default_pool.id
-
- assert_response :redirect
- assert_redirected_to :controller => 'resources', :action => 'show'
-
+ get :new, :hardware_pool_id => @default_pool.id, :format => "json"
+ json = ActiveSupport::JSON.decode(@response.body)
+ assert_equal 'You do not have permission to create or modify this item ', json['alert']
assert_not_nil assigns(:vm)
end
diff --git a/src/test/unit/active_record_env_test.rb b/src/test/unit/active_record_env_test.rb
index 30db689..26fa139 100644
--- a/src/test/unit/active_record_env_test.rb
+++ b/src/test/unit/active_record_env_test.rb
@@ -22,8 +22,8 @@ require File.dirname(__FILE__) + '/../../dutils/active_record_env'
class ActiveRecordEnvTest < Test::Unit::TestCase
fixtures :pools, :hosts, :vms, :boot_types,
- :networks, :nics, :ip_addresses, :permissions, :quotas,
- :storage_pools, :storage_volumes, :tasks
+ :networks, :nics, :ip_addresses, :privileges, :roles, :permissions,
+ :quotas, :storage_pools, :storage_volumes, :tasks
def test_can_find_hosts
database_connect
diff --git a/src/test/unit/permission_test.rb b/src/test/unit/permission_test.rb
index 0c0f4c7..2ac78d5 100644
--- a/src/test/unit/permission_test.rb
+++ b/src/test/unit/permission_test.rb
@@ -20,19 +20,19 @@
require File.dirname(__FILE__) + '/../test_helper'
class PermissionTest < Test::Unit::TestCase
- fixtures :permissions
+ fixtures :privileges, :roles, :permissions
fixtures :pools
def setup
@permission = Permission.new(
:uid => 'foobar',
- :user_role => 'Super Admin' )
+ :role_id => Role.find_by_name(Role::SUPER_ADMIN).id )
@permission.pool = pools(:root_dir_pool)
end
# Replace this with your real tests.
def test_simple_permission
- assert_equal permissions(:ovirtadmin_root).user_role, 'Super Admin'
+ assert_equal permissions(:ovirtadmin_root).role.name, 'Super Admin'
assert_equal permissions(:ovirtadmin_root).pool.name, 'root'
end
@@ -51,13 +51,9 @@ class PermissionTest < Test::Unit::TestCase
flunk 'Permission must specify uid' if @permission.valid?
end
- def test_valid_fails_without_user_role
- @permission.user_role = ''
- flunk 'Permission must specify user role' if @permission.valid?
+ def test_valid_fails_without_role_id
+ @permission.role_id = ''
+ flunk 'Permission must specify role' if @permission.valid?
end
- def test_valid_fails_with_invalid_user_role
- @permission.user_role = 'foobar'
- flunk 'Permission must specify valid user role' if @permission.valid?
- end
end
diff --git a/src/test/unit/task_test.rb b/src/test/unit/task_test.rb
index ba780e7..761e739 100644
--- a/src/test/unit/task_test.rb
+++ b/src/test/unit/task_test.rb
@@ -20,7 +20,7 @@
require File.dirname(__FILE__) + '/../test_helper'
class TaskTest < Test::Unit::TestCase
- fixtures :pools, :hosts, :vms, :permissions, :tasks
+ fixtures :pools, :hosts, :vms, :privileges, :roles, :permissions, :tasks
def setup
@task = Task.new( :type => 'HostTask', :state => 'finished' )
--
1.6.0.6
More information about the ovirt-devel
mailing list