Permalink
Browse files

Enable OrgManager permission(s) for app model

Change-Id: I861069f2100205485a661cff543d347b4e46d4c8
  • Loading branch information...
1 parent 69f32c1 commit 796f2307c7dd8ca62326824d45c97bc02088f421 @kowshik kowshik committed Jan 24, 2013
@@ -6,7 +6,6 @@ module VCAP::CloudController
full Permissions::CFAdmin
read Permissions::OrgManager
read Permissions::SpaceManager
- read Permissions::SpaceManager
full Permissions::SpaceDeveloper
read Permissions::SpaceAuditor
end
@@ -9,6 +9,11 @@ def self.granted_to_via_org?(obj, user, relation)
if obj.kind_of?(Models::Organization)
obj.send(relation).include?(user)
+ elsif obj.kind_of?(Models::App)
+ if (obj.space && obj.space.organization &&
+ obj.space.organization.send("#{relation}_dataset")[:id => user.id] != nil)
+ return true
+ end
elsif !obj.new?
if obj.respond_to?(:owning_organization)
return false unless obj.owning_organization
@@ -7,11 +7,25 @@ class SpacePermissions
def self.granted_to_via_space?(obj, user, relation)
return false if user.nil?
+ space_contains?(obj, user, relation) ||
+ related_space_contains_user?(obj, user, relation) ||
+ any_related_space_contains_user?(obj, user, relation)
+ end
+
+ def self.space_contains?(obj, user, relation)
if obj.kind_of?(Models::Space)
obj.send(relation).include?(user)
- elsif !obj.new? && obj.respond_to?(:spaces)
+ end
+ end
+
+ def self.any_related_space_contains_user?(obj, user, relation)
+ if !obj.new? && obj.respond_to?(:spaces)
obj.spaces_dataset.filter(relation => [user]).count >= 1
- elsif !obj.new? && obj.respond_to?(:space)
+ end
+ end
+
+ def self.related_space_contains_user?(obj, user, relation)
+ if !obj.new? && obj.respond_to?(:space)
obj.space.send("#{relation}_dataset")[user.id] != nil
end
end
View
@@ -378,10 +378,11 @@ module VCAP::CloudController
end
let(:creation_req_for_a) do
- Yajl::Encoder.encode(:name => Sham.name,
- :space_guid => @space_a.guid,
- :framework_guid => Models::Framework.make.guid,
- :runtime_guid => Models::Runtime.make.guid)
+ Yajl::Encoder.encode(
+ :name => Sham.name,
+ :space_guid => @space_a.guid,
+ :framework_guid => Models::Framework.make.guid,
+ :runtime_guid => Models::Runtime.make.guid)
end
let(:update_req_for_a) do
@@ -398,7 +399,7 @@ module VCAP::CloudController
:path => "/v2/apps",
:enumerate => 0,
:create => :not_allowed,
- :read => :not_allowed,
+ :read => :allowed,
:modify => :not_allowed,
:delete => :not_allowed
end
@@ -3,7 +3,7 @@
require File.expand_path("../spec_helper", __FILE__)
module VCAP::CloudController
- describe VCAP::CloudController::AppSummary do
+ describe AppSummary do
let(:admin_headers) do
user = VCAP::CloudController::Models::User.make(:admin => true)
headers_for(user)
@@ -13,8 +13,9 @@ module VCAP::CloudController
@num_services = 2
@free_mem_size = 128
- @system_domain = Models::Domain.new(:name => Sham.domain,
- :owning_organization => nil)
+ @system_domain = Models::Domain.new(
+ :name => Sham.domain,
+ :owning_organization => nil)
@system_domain.save(:validate => false)
@space = Models::Space.make
@@ -27,7 +28,7 @@ module VCAP::CloudController
:production => false,
:instances => 1,
:memory => @free_mem_size,
- :state => "STARTED",
+ :state => "STARTED"
)
@num_services.times do
@@ -109,7 +110,7 @@ module VCAP::CloudController
]
end
- it "should return num_services services" do
+ it "should return correct number of services" do
decoded_response["services"].size.should == @num_services
end
@@ -134,5 +135,95 @@ module VCAP::CloudController
}
end
end
+
+ describe "Permissions" do
+ include_context "permissions"
+
+ before do
+ @obj_a = Models::App.make(:space => @space_a)
+ @obj_b = Models::App.make(:space => @space_b)
+ end
+
+ describe "Org Level Permissions" do
+ describe "OrgManager" do
+ let(:member_a) { @org_a_manager }
+ let(:member_b) { @org_b_manager }
+
+ include_examples "read permission check", "OrgManager",
+ :model => Models::App,
+ :path => "/v2/apps",
+ :path_suffix => "/summary",
+ :allowed => true
+ end
+
+ describe "OrgUser" do
+ let(:member_a) { @org_a_member }
+ let(:member_b) { @org_b_member }
+
+ include_examples "read permission check", "OrgUser",
+ :model => Models::App,
+ :path => "/v2/apps",
+ :path_suffix => "/summary",
+ :allowed => false
+ end
+
+ describe "BillingManager" do
+ let(:member_a) { @org_a_billing_manager }
+ let(:member_b) { @org_b_billing_manager }
+
+ include_examples "read permission check", "BillingManager",
+ :model => Models::App,
+ :path => "/v2/apps",
+ :path_suffix => "/summary",
+ :allowed => false
+ end
+
+ describe "Auditor" do
+ let(:member_a) { @org_a_auditor }
+ let(:member_b) { @org_b_auditor }
+
+ include_examples "read permission check", "Auditor",
+ :model => Models::App,
+ :path => "/v2/apps",
+ :path_suffix => "/summary",
+ :allowed => false
+ end
+ end
+
+ describe "App Space Level Permissions" do
+ describe "SpaceManager" do
+ let(:member_a) { @space_a_manager }
+ let(:member_b) { @space_b_manager }
+
+ include_examples "read permission check", "SpaceManager",
+ :model => Models::App,
+ :path => "/v2/apps",
+ :path_suffix => "/summary",
+ :allowed => true
+ end
+
+ describe "Developer" do
+ let(:member_a) { @space_a_developer }
+ let(:member_b) { @space_b_developer }
+
+ include_examples "read permission check", "Developer",
+ :model => Models::App,
+ :path => "/v2/apps",
+ :path_suffix => "/summary",
+ :allowed => true
+ end
+
+ describe "SpaceAuditor" do
+ let(:member_a) { @space_a_auditor }
+ let(:member_b) { @space_b_auditor }
+
+ include_examples "read permission check", "SpaceAuditor",
+ :model => Models::App,
+ :path => "/v2/apps",
+ :path_suffix => "/summary",
+ :allowed => true
+ end
+ end
+ end
end
end
@@ -54,10 +54,9 @@ module VCAP::CloudController::ApiSpecHelper
end
end
- shared_examples "permission enumeration" do |perm_name, model, name, path, expected, perms_overlap|
+ shared_examples "permission enumeration" do |perm_name, model, name, path, path_suffix, expected, perms_overlap|
describe "GET #{path}" do
it "should return #{expected} #{name.pluralize} to a user that has #{perm_name} permissions" do
-
get path, {}, headers_a
last_response.should be_ok
decoded_response["total_results"].should == expected
@@ -81,34 +80,34 @@ module VCAP::CloudController::ApiSpecHelper
unless perms_overlap
it "should not return a #{name} to a user with the #{perm_name} permission on a different #{name}" do
- get "#{path}/#{@obj_a.guid}", {}, headers_b
+ get "#{path}/#{@obj_a.guid}#{path_suffix}", {}, headers_b
last_response.should_not be_ok
end
end
end
end
- shared_examples "permission create allowed" do |perm_name, model, name, path, perms_overlap|
+ shared_examples "permission create allowed" do |perm_name, model, name, path, path_suffix, perms_overlap|
describe "POST #{path}" do
it "should allow a user with the #{perm_name} permission to create a #{name}" do
- before_count = model.count
- post path, creation_req_for_a, json_headers(headers_a)
- last_response.status.should == 201
- model.count.should == before_count + 1
+ expect {
+ post path, creation_req_for_a, json_headers(headers_a)
+ last_response.status.should == 201
+ }.to change { model.count }.by(1)
end
unless perms_overlap
it "should not allow a user with the #{perm_name} permission for a different service instance to create a service instance" do
- before_count = model.count
- post path, creation_req_for_a, json_headers(headers_b)
- last_response.status.should == 403
- model.count.should == before_count
+ expect {
+ post path, creation_req_for_a, json_headers(headers_b)
+ last_response.status.should == 403
+ }.to_not change { model.count }
end
end
end
end
- shared_examples "permission create not_allowed" do |perm_name, model, name, path|
+ shared_examples "permission create not_allowed" do |perm_name, model, name, path, path_suffix, perms_overlap|
describe "POST #{path}" do
it "should not allow a user with only the #{perm_name} permission to create a #{name}" do
post path, creation_req_for_a, json_headers(headers_a)
@@ -117,94 +116,109 @@ module VCAP::CloudController::ApiSpecHelper
end
end
- shared_examples "permission modify allowed" do |perm_name, model, name, path, perms_overlap|
+ shared_examples "permission modify allowed" do |perm_name, model, name, path, path_suffix, perms_overlap|
describe "PUT #{path}/:id" do
it "should allow a user with the #{perm_name} permission to modify a #{name}" do
- put "#{path}/#{@obj_a.guid}", update_req_for_a, json_headers(headers_a)
+ put "#{path}/#{@obj_a.guid}#{path_suffix}", update_req_for_a, json_headers(headers_a)
last_response.status.should == 201
decoded_response["metadata"]["guid"].should == @obj_a.guid
end
unless perms_overlap
it "should not allow a user with the #{perm_name} permission for a different #{name} to modify a #{name}" do
- put "#{path}/#{@obj_a.guid}", update_req_for_a, json_headers(headers_b)
+ put "#{path}/#{@obj_a.guid}#{path_suffix}", update_req_for_a, json_headers(headers_b)
last_response.status.should == 403
end
end
end
end
- shared_examples "permission modify not_allowed" do |perm_name, model, name, path|
+ shared_examples "permission modify not_allowed" do |perm_name, model, name, path, path_suffix, perms_overlap|
describe "PUT /v2/service_instances/:id" do
it "should not allow a user with only the #{perm_name} permission to modify a #{name}" do
- put "#{path}/#{@obj_a.guid}", update_req_for_a, json_headers(headers_a)
+ put "#{path}/#{@obj_a.guid}#{path_suffix}", update_req_for_a, json_headers(headers_a)
last_response.status.should == 403
end
end
end
- shared_examples "permission read not_allowed" do |perm_name, model, name, path|
+ shared_examples "permission read not_allowed" do |perm_name, model, name, path, path_suffix, perms_overlap|
describe "GET #{path}/:id" do
it "should not allow a user with only the #{perm_name} permission to read a #{name}" do
- get "#{path}/#{@obj_a.guid}", {}, headers_a
+ get "#{path}/#{@obj_a.guid}#{path_suffix}", {}, headers_a
last_response.status.should == 403
end
end
end
- shared_examples "permission read allowed" do |perm_name, model, name, path, perms_overlap|
+ shared_examples "permission read allowed" do |perm_name, model, name, path, path_suffix, perms_overlap|
describe "GET #{path}/:id" do
it "should allow a user with the #{perm_name} permission to read a #{name}" do
- get "#{path}/#{@obj_a.guid}", {}, headers_a
- last_response.should be_ok
- decoded_response["metadata"]["guid"].should == @obj_a.guid
+ get "#{path}/#{@obj_a.guid}#{path_suffix}", {}, headers_a
+ last_response.status.should == 200
+
+ returned_guid = (path_suffix == "/summary") ? decoded_response["guid"] : decoded_response["metadata"]["guid"]
+ returned_guid.should == @obj_a.guid
end
unless perms_overlap
it "should not allow a user with the #{perm_name} permission for another #{name} to read a #{name}" do
- get "#{path}/#{@obj_a.guid}", {}, headers_b
- last_response.should_not be_ok
+ get "#{path}/#{@obj_a.guid}#{path_suffix}", {}, headers_b
+ last_response.status.should == 403
end
end
end
end
- shared_examples "permission delete allowed" do |perm_name, model, name, path, perms_overlap|
+ shared_examples "permission delete allowed" do |perm_name, model, name, path, path_suffix, perms_overlap|
describe "DELETE /v2/apps/:id" do
it "should allow a user with the #{perm_name} permission to delete a #{name}" do
- delete "#{path}/#{@obj_a.guid}", {}, headers_a
+ delete "#{path}/#{@obj_a.guid}#{path_suffix}", {}, headers_a
last_response.status.should == 204
end
unless perms_overlap
it "should not allow a user with the #{perm_name} permission for a different #{name} to delete a #{name}" do
- delete "#{path}/#{@obj_a.guid}", {}, headers_b
+ delete "#{path}/#{@obj_a.guid}#{path_suffix}", {}, headers_b
last_response.status.should == 403
end
end
end
end
- shared_examples "permission delete not_allowed" do |perm_name, model, name, path|
+ shared_examples "permission delete not_allowed" do |perm_name, model, name, path, path_suffix, perms_overlap|
describe "DELETE #{path}/:id" do
it "should not allow a user with only the #{perm_name} permission to delete a #{name}" do
- delete "#{path}/#{@obj_a.guid}", {}, headers_a
+ delete "#{path}/#{@obj_a.guid}#{path_suffix}", {}, headers_a
last_response.status.should == 403
end
end
end
shared_examples "permission checks" do |perm_name, opts|
model = opts[:model]
- path = opts[:path]
name = model.name.split("::").last.underscore.gsub("_", " ")
+
+ path = opts[:path]
+ path_suffix = opts[:path_suffix]
perms_overlap = opts[:permissions_overlap]
include_examples "permission enumeration",
- perm_name, model, name, path, opts[:enumerate], perms_overlap
+ perm_name, model, name, path, path_suffix, opts[:enumerate], perms_overlap
[:create, :read, :modify, :delete].each do |op|
- include_examples "permission #{op} #{opts[op]}", perm_name, model, name, path, perms_overlap
+ include_examples "permission #{op} #{opts[op]}", perm_name, model, name, path, path_suffix, perms_overlap
end
end
+
+ shared_examples "read permission check" do |perm_name, opts|
+ model = opts[:model]
+ name = model.name.split("::").last.underscore.gsub("_", " ")
+
+ path = opts[:path]
+ path_suffix = opts[:path_suffix]
+
+ include_examples "permission read #{opts[:allowed] ? "allowed" : "not_allowed"}",
+ perm_name, model, name, path, path_suffix, false
+ end
end
Oops, something went wrong.

0 comments on commit 796f230

Please sign in to comment.