Signed-off-by: Scott Seago <sseago(a)redhat.com>
---
.../controllers/admin/pool_families_controller.rb | 1 +
.../admin/provider_accounts_controller.rb | 1 +
src/app/controllers/admin/providers_controller.rb | 1 +
.../image_factory/templates_controller.rb | 1 +
src/app/controllers/instances_controller.rb | 2 +
.../controllers/resources/instances_controller.rb | 2 +
src/app/controllers/resources/pools_controller.rb | 1 +
src/app/models/permissioned_object.rb | 16 ++++-
src/db/migrate/20110119000000_owner_roles.rb | 46 +++++++++++
src/db/seeds.rb | 85 ++++++++++----------
src/spec/controllers/instance_controller_spec.rb | 29 +++++++
src/spec/factories/permission.rb | 8 ++-
src/spec/factories/user.rb | 5 +
13 files changed, 154 insertions(+), 44 deletions(-)
create mode 100644 src/db/migrate/20110119000000_owner_roles.rb
diff --git a/src/app/controllers/admin/pool_families_controller.rb
b/src/app/controllers/admin/pool_families_controller.rb
index 9fe2c25..42bfb04 100644
--- a/src/app/controllers/admin/pool_families_controller.rb
+++ b/src/app/controllers/admin/pool_families_controller.rb
@@ -15,6 +15,7 @@ class Admin::PoolFamiliesController < ApplicationController
flash.now[:warning] = "Pool family's creation failed."
render :new and return
else
+ @pool_family.assign_owner_roles(current_user)
flash[:notice] = "Pool family was added."
redirect_to admin_pool_families_path
end
diff --git a/src/app/controllers/admin/provider_accounts_controller.rb
b/src/app/controllers/admin/provider_accounts_controller.rb
index d422a53..132d8a1 100644
--- a/src/app/controllers/admin/provider_accounts_controller.rb
+++ b/src/app/controllers/admin/provider_accounts_controller.rb
@@ -73,6 +73,7 @@ class Admin::ProviderAccountsController < ApplicationController
@cloud_account.pool_families << PoolFamily.default
@cloud_account.save!
+ @cloud_account.assign_owner_roles(current_user)
if @cloud_account.populate_realms
flash[:notice] = "Provider account added."
end
diff --git a/src/app/controllers/admin/providers_controller.rb
b/src/app/controllers/admin/providers_controller.rb
index a898d72..0490af8 100644
--- a/src/app/controllers/admin/providers_controller.rb
+++ b/src/app/controllers/admin/providers_controller.rb
@@ -54,6 +54,7 @@ class Admin::ProvidersController < ApplicationController
else
@provider.set_cloud_type!
if @provider.save && @provider.populate_hardware_profiles
+ @provider.assign_owner_roles(current_user)
flash[:notice] = "Provider added."
redirect_to admin_providers_path
else
diff --git a/src/app/controllers/image_factory/templates_controller.rb
b/src/app/controllers/image_factory/templates_controller.rb
index 11f410b..58caecd 100644
--- a/src/app/controllers/image_factory/templates_controller.rb
+++ b/src/app/controllers/image_factory/templates_controller.rb
@@ -72,6 +72,7 @@ class ImageFactory::TemplatesController < ApplicationController
@tpl = Template.new(params[:tpl])
@tpl.packages = params[:packages]
if @tpl.save
+ @tpl.assign_owner_roles(current_user)
flash[:notice] = "Template saved."
@tpl.set_complete
redirect_to image_factory_templates_path
diff --git a/src/app/controllers/instances_controller.rb
b/src/app/controllers/instances_controller.rb
index e22aea4..e877729 100644
--- a/src/app/controllers/instances_controller.rb
+++ b/src/app/controllers/instances_controller.rb
@@ -101,6 +101,8 @@ class InstancesController < ApplicationController
Pool.find((a)instance.pool_id))
#FIXME: This should probably be in a transaction
if @instance.save!
+ # set owner permissions:
+ @instance.assign_owner_roles(current_user)
@task = InstanceTask.new({:user => current_user,
:task_target => @instance,
:action => InstanceTask::ACTION_CREATE})
diff --git a/src/app/controllers/resources/instances_controller.rb
b/src/app/controllers/resources/instances_controller.rb
index 9482a8d..9d2b5c8 100644
--- a/src/app/controllers/resources/instances_controller.rb
+++ b/src/app/controllers/resources/instances_controller.rb
@@ -55,6 +55,8 @@ class Resources::InstancesController < ApplicationController
free_quota = Quota.can_start_instance?(@instance, nil)
@instance.transaction do
@instance.save!
+ # set owner permissions:
+ @instance.assign_owner_roles(current_user)
@task = InstanceTask.create!({:user => current_user,
:task_target => @instance,
:action => InstanceTask::ACTION_CREATE})
diff --git a/src/app/controllers/resources/pools_controller.rb
b/src/app/controllers/resources/pools_controller.rb
index c5988ca..b2bc8f9 100644
--- a/src/app/controllers/resources/pools_controller.rb
+++ b/src/app/controllers/resources/pools_controller.rb
@@ -48,6 +48,7 @@ class Resources::PoolsController < ApplicationController
@pool.quota_id = quota.id
@pool.pool_family = PoolFamily.default
if @pool.save
+ @pool.assign_owner_roles(current_user)
flash[:notice] = "Pool added."
redirect_to :action => 'show', :id => @pool.id
else
diff --git a/src/app/models/permissioned_object.rb
b/src/app/models/permissioned_object.rb
index 34efec8..ee2685f 100644
--- a/src/app/models/permissioned_object.rb
+++ b/src/app/models/permissioned_object.rb
@@ -41,6 +41,20 @@ module PermissionedObject
[self, BasePermissionObject.general_permission_scope]
end
+ # assign owner role so that the creating user has permissions on the object
+ # Any roles defined on default_privilege_target_type with assign_to_owner==true
+ # will be assigned to the passed-in user on this object
+ def assign_owner_roles(user)
+ roles = Role.find(:all, :conditions => ["assign_to_owner =:assign and
scope=:scope",
+ { :assign => true,
+ :scope =>
self.class.default_privilege_target_type.name}])
+ roles.each do |role|
+ permission = Permission.create!(:role => role,
+ :user => user,
+ :permission_object => self)
+ end
+ end
+
# Any methods here will be able to use the context of the
# ActiveRecord model the module is included in.
def self.included(base)
@@ -82,7 +96,7 @@ module PermissionedObject
if query_conditions.nil?
conditions_str = self.list_for_user_conditions
else
- conditions_str = "(#{self.list_for_user_include}) and
(#{query_conditions[0]})"
+ conditions_str = "(#{self.list_for_user_conditions}) and
(#{query_conditions[0]})"
conditions_hash.merge!(query_conditions[1]) { |key, h1, h2| h1 }
end
find(:all, :include => include_clause,
diff --git a/src/db/migrate/20110119000000_owner_roles.rb
b/src/db/migrate/20110119000000_owner_roles.rb
new file mode 100644
index 0000000..15ebd84
--- /dev/null
+++ b/src/db/migrate/20110119000000_owner_roles.rb
@@ -0,0 +1,46 @@
+#
+# Copyright (C) 2011 Red Hat, Inc.
+# Written by Scott Seago <sseago(a)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 OwnerRoles < ActiveRecord::Migration
+
+ OWNER_ROLES = ["Instance Owner",
+ "Pool Family Owner",
+ "Pool Owner",
+ "Provider Owner",
+ "Provider Account Owner",
+ "Template Owner"]
+
+ def self.up
+ add_column :roles, :assign_to_owner, :boolean, :default => false
+
+ Role.transaction do
+ OWNER_ROLES.each do |role_name|
+ role = Role.find_by_name(role_name)
+ unless role.nil?
+ role.assign_to_owner = true
+ role.save!
+ end
+ end
+ end
+ end
+
+ def self.down
+ remove_column :roles, :assign_to_owner
+ end
+end
diff --git a/src/db/seeds.rb b/src/db/seeds.rb
index 9a6065c..71726bf 100644
--- a/src/db/seeds.rb
+++ b/src/db/seeds.rb
@@ -15,57 +15,58 @@ GPRM = "set_perms"
roles =
{Instance =>
- {"Instance Controller" => {Instance => [VIEW,USE]},
- "Instance Owner" => {Instance => [VIEW,USE,MOD,
VPRM,GPRM]}},
+ {"Instance Controller" => [false, {Instance => [VIEW,USE]}],
+ "Instance Owner" => [true, {Instance => [VIEW,USE,MOD,
VPRM,GPRM]}]},
PoolFamily =>
- {"Pool Family User" => {Pool => [VIEW]},
- "Pool Family Owner" => {PoolFamily => [VIEW, MOD,
VPRM,GPRM],
- Pool => [VIEW, MOD,CRE,VPRM,GPRM]}},
+ {"Pool Family User" => [false, {Pool => [VIEW]}],
+ "Pool Family Owner" => [true, {PoolFamily => [VIEW, MOD,
VPRM,GPRM],
+ Pool => [VIEW,
MOD,CRE,VPRM,GPRM]}]},
Pool =>
- {"Pool User" => {Pool => [VIEW],
- Instance => [ CRE],
- Quota => [VIEW]},
- "Pool Owner" => {Pool => [VIEW, MOD,
VPRM,GPRM],
- Instance => [VIEW,USE,MOD,CRE],
- Quota => [VIEW]}},
+ {"Pool User" => [false, {Pool => [VIEW],
+ Instance => [ CRE],
+ Quota => [VIEW]}],
+ "Pool Owner" => [true, {Pool => [VIEW, MOD,
VPRM,GPRM],
+ Instance => [VIEW,USE,MOD,CRE],
+ Quota => [VIEW]}]},
Provider =>
- {"Provider Owner" => {Provider => [VIEW, MOD,
VPRM,GPRM],
- CloudAccount => [VIEW,USE,MOD,CRE,VPRM,GPRM]}},
+ {"Provider Owner" => [true, {Provider => [VIEW, MOD,
VPRM,GPRM],
+ CloudAccount =>
[VIEW,USE,MOD,CRE,VPRM,GPRM]}]},
CloudAccount =>
- {"Provider Account User" => {CloudAccount => [VIEW,USE]},
- "Provider Account Owner" => {CloudAccount => [VIEW,USE,MOD,
VPRM,GPRM]}},
+ {"Provider Account User" => [false, {CloudAccount => [VIEW,USE]}],
+ "Provider Account Owner" => [true, {CloudAccount => [VIEW,USE,MOD,
VPRM,GPRM]}]},
Template =>
- {"Template User" => {Template => [VIEW,USE]},
- "Template Owner" => {Template => [VIEW,USE,MOD,
VPRM,GPRM]}},
+ {"Template User" => [false, {Template => [VIEW,USE]}],
+ "Template Owner" => [true, {Template => [VIEW,USE,MOD,
VPRM,GPRM]}]},
BasePermissionObject =>
- {"Provider Creator" => {Provider => [ CRE]},
- "Provider Administrator" => {Provider => [VIEW,
MOD,CRE,VPRM,GPRM],
- CloudAccount => [VIEW,USE,MOD,CRE,VPRM,GPRM]},
- "HWP Administrator" => {HardwareProfile => [
MOD,CRE,VPRM,GPRM]},
- "Realm Administrator" => {Realm => [
USE,MOD,CRE,VPRM,GPRM]},
- "Pool Creator" => {Pool => [ CRE]},
- "Pool Administrator" => {Pool => [VIEW,
MOD,CRE,VPRM,GPRM],
- Instance => [VIEW,USE,MOD,CRE,VPRM,GPRM],
- Quota => [VIEW, MOD],
- PoolFamily => [VIEW, MOD,CRE,VPRM,GPRM]},
- "Template Administrator" => {Template =>
[VIEW,USE,MOD,CRE,VPRM,GPRM]},
- "Administrator" => {Provider => [VIEW,
MOD,CRE,VPRM,GPRM],
- CloudAccount => [VIEW,USE,MOD,CRE,VPRM,GPRM],
- HardwareProfile => [ MOD,CRE,VPRM,GPRM],
- Realm => [ USE,MOD,CRE,VPRM,GPRM],
- User => [VIEW, MOD,CRE],
- Pool => [VIEW, MOD,CRE,VPRM,GPRM],
- Instance => [VIEW,USE,MOD,CRE,VPRM,GPRM],
- Quota => [VIEW, MOD],
- PoolFamily => [VIEW, MOD,CRE,VPRM,GPRM],
- Template => [VIEW,USE,MOD,CRE,VPRM,GPRM],
- BasePermissionObject => [ MOD, VPRM,GPRM]}}}
+ {"Provider Creator" => [false, {Provider => [
CRE]}],
+ "Provider Administrator" => [false, {Provider => [VIEW,
MOD,CRE,VPRM,GPRM],
+ CloudAccount =>
[VIEW,USE,MOD,CRE,VPRM,GPRM]}],
+ "HWP Administrator" => [false, {HardwareProfile => [
MOD,CRE,VPRM,GPRM]}],
+ "Realm Administrator" => [false, {Realm => [
USE,MOD,CRE,VPRM,GPRM]}],
+ "Pool Creator" => [false, {Pool => [
CRE]}],
+ "Pool Administrator" => [false, {Pool => [VIEW,
MOD,CRE,VPRM,GPRM],
+ Instance =>
[VIEW,USE,MOD,CRE,VPRM,GPRM],
+ Quota => [VIEW, MOD],
+ PoolFamily => [VIEW,
MOD,CRE,VPRM,GPRM]}],
+ "Template Administrator" => [false, {Template =>
[VIEW,USE,MOD,CRE,VPRM,GPRM]}],
+ "Administrator" => [false, {Provider => [VIEW,
MOD,CRE,VPRM,GPRM],
+ CloudAccount =>
[VIEW,USE,MOD,CRE,VPRM,GPRM],
+ HardwareProfile => [
MOD,CRE,VPRM,GPRM],
+ Realm => [
USE,MOD,CRE,VPRM,GPRM],
+ User => [VIEW, MOD,CRE],
+ Pool => [VIEW,
MOD,CRE,VPRM,GPRM],
+ Instance =>
[VIEW,USE,MOD,CRE,VPRM,GPRM],
+ Quota => [VIEW, MOD],
+ PoolFamily => [VIEW,
MOD,CRE,VPRM,GPRM],
+ Template =>
[VIEW,USE,MOD,CRE,VPRM,GPRM],
+ BasePermissionObject => [ MOD,
VPRM,GPRM]}]}}
Role.transaction do
roles.each do |role_scope, scoped_hash|
- scoped_hash.each do |role_name, role_privileges|
- role_privileges.each do |priv_type, priv_actions|
+ scoped_hash.each do |role_name, role_def|
+ role_def[1].each do |priv_type, priv_actions|
role = Role.find_or_initialize_by_name(role_name)
- role.update_attributes({:name => role_name, :scope => role_scope.name})
+ role.update_attributes({:name => role_name, :scope => role_scope.name,
+ :assign_to_owner => role_def[0]})
role.save!
priv_actions.each do |action|
Privilege.create!(:role => role, :target_type => priv_type.name,
diff --git a/src/spec/controllers/instance_controller_spec.rb
b/src/spec/controllers/instance_controller_spec.rb
index 34a44c8..628f53a 100644
--- a/src/spec/controllers/instance_controller_spec.rb
+++ b/src/spec/controllers/instance_controller_spec.rb
@@ -38,4 +38,33 @@ describe InstancesController do
inst = Instance.find(:first, :conditions => ['name = ?',
'mockinstance'])
inst.owner_id.should == @pool_user.id
end
+
+ it "should NOT allow pool users to see each other's instances" do
+ @pool_user_permission = Factory :pool_user_permission
+ @pool_user = @pool_user_permission.user
+ @pool_user2_permission = Factory :pool_user2_permission
+ @pool_user2 = @pool_user2_permission.user
+ UserSession.create(@pool_user)
+ pool = Permission.first(:conditions => {:permission_object_type =>
'Pool', :user_id => @pool_user.id}).permission_object
+ template = Factory.build(:template)
+ template.save!
+ hwp = Factory.build(:mock_hwp1)
+ hwp.save!
+ lambda do
+ post :create, :instance => { :name => 'mockinstance',
+ :pool_id => pool.id,
+ :template_id => template.id,
+ :hardware_profile_id => hwp.id }
+ end.should change(Instance, :count).by(1)
+ inst = Instance.find(:first, :conditions => ['name = ?',
'mockinstance'])
+ inst.permissions.size.should == 1
+ inst.permissions[0].user.should == @pool_user
+ inst = Instance.list_for_user(@pool_user, Privilege::MODIFY,
+ :conditions => ['instances.name = :name',
+ {:name =>
'mockinstance'}]).size.should == 1
+ inst = Instance.list_for_user(@pool_user2, Privilege::MODIFY,
+ :conditions => ['instances.name = :name',
+ {:name =>
'mockinstance'}]).size.should == 0
+
+ end
end
diff --git a/src/spec/factories/permission.rb b/src/spec/factories/permission.rb
index f260ad7..7d988c5 100644
--- a/src/spec/factories/permission.rb
+++ b/src/spec/factories/permission.rb
@@ -23,5 +23,11 @@ end
Factory.define :pool_user_permission, :parent => :permission do |p|
p.role { |r| Role.first(:conditions => ['name = ?', 'Pool User']) ||
Factory(:role, :name => 'Pool User') }
p.permission_object { |r| r.association(:pool) }
- p.user { |u| u.association(:user) }
+ p.user { |u| u.association(:pool_user) }
+end
+
+Factory.define :pool_user2_permission, :parent => :permission do |p|
+ p.role { |r| Role.first(:conditions => ['name = ?', 'Pool User']) ||
Factory(:role, :name => 'Pool User') }
+ p.permission_object { |r| r.association(:pool) }
+ p.user { |u| u.association(:pool_user2) }
end
diff --git a/src/spec/factories/user.rb b/src/spec/factories/user.rb
index a9dd23e..2dc94f0 100644
--- a/src/spec/factories/user.rb
+++ b/src/spec/factories/user.rb
@@ -24,3 +24,8 @@ Factory.define :pool_user, :parent => :user do |u|
u.sequence(:login) { |n| "pool_user#{n}" }
u.email { |e| "#{e.login}(a)example.com" }
end
+
+Factory.define :pool_user2, :parent => :user do |u|
+ u.sequence(:login) { |n| "pool_user2#{n}" }
+ u.email { |e| "#{e.login}(a)example.com" }
+end
--
1.7.3.4