Adds a conditional_link method to ApplicationHelper to link to an object only if @current_user has permission to view it. Also adds a requisite find_link_to method to emulate link_to(object) functionality lost when using namespaces in routes. --- src/app/helpers/application_helper.rb | 29 +++++++++++++++++++++++++++ src/spec/helpers/application_helper_spec.rb | 28 ++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 0 deletions(-)
diff --git a/src/app/helpers/application_helper.rb b/src/app/helpers/application_helper.rb index c536a81..c8e42bd 100644 --- a/src/app/helpers/application_helper.rb +++ b/src/app/helpers/application_helper.rb @@ -194,4 +194,33 @@ module ApplicationHelper title.split(' ').join('_').downcase end
+ # Link to an object only if it can be viewed by the current user + def conditional_link(attr, object) + if object.present? && object.has_privilege(@current_user, Privilege::VIEW) + link_to object.send(attr), find_link_to(object) + else + object.present? ? object.send(attr) : '' + end + end + + # Try to allow simple link_to even though we use namespaces in routes + def find_link_to(object) + ns_resources = ['Pool', 'Deployment', 'Instance'] + ns_image_factory = ['Assembly', 'Deployable', 'Template'] + ns_admin = ['HardwareProfile', 'Provider', 'User', 'ProviderAccount', 'Role', 'PoolFamily', 'Realm'] + + class_path = object.class.name.underscore + link = nil + if ns_resources.include?(object.class.name) + link = "resources_#{class_path}_path" + elsif ns_image_factory.include?(object.class.name) + link = "image_factory_#{class_path}_path" + elsif ns_admin.include?(object.class.name) + link = "admin_#{class_path}_path" + else + raise "No route for #{class_path}" + end + ActionController::Integration::Session.new.send(link, object) + end + end diff --git a/src/spec/helpers/application_helper_spec.rb b/src/spec/helpers/application_helper_spec.rb index fe5c956..947df05 100644 --- a/src/spec/helpers/application_helper_spec.rb +++ b/src/spec/helpers/application_helper_spec.rb @@ -34,4 +34,32 @@ describe ApplicationHelper do
end
+ context "find_link_to helper" do + it "has route for admin_users" do + find_link_to(Factory(:user)).match('^/admin/users/').should be_true + end + it "has route for resources_pool" do + find_link_to(Factory(:pool)).match('^/resources/pools/').should be_true + end + it "should raise error for bogus routes" do + lambda { find_link_to(Factory(:quota)) }.should raise_error(RuntimeError) + end + end + + context "conditional_link helper" do + it "links to viewable pool" do + @pool_user_permission = Factory(:pool_user_permission) + @pool = @pool_user_permission.permission_object + @current_user = @pool_user_permission.user + conditional_link(:name, @pool).match('^<a href="/resources/pools').should be_true + end + + it "does not link to non-viewable pool" do + @pool_user_permission = Factory(:pool_user_permission) + @pool = @pool_user_permission.permission_object + @current_user = Factory(:pool_user2_permission).user + conditional_link(:name, @pool).match("^mypool").should be_true + end + end + end