ref: refs/heads/master
commit 73fd44fdad6afc1c0a90daf56ca65a59eb90c4c4
Author: Klaus Kämpf
Date: Thu Jul 9 15:02:54 2009 +0200
Refactor, cleanup, stabilize, test PermissionsController
---
.../app/controllers/permissions_controller.rb | 160 ++++++++++++--------
webservice/app/models/permission.rb | 9 +-
.../test/functional/permissions_controller_test.rb | 21 ++-
3 files changed, 118 insertions(+), 72 deletions(-)
diff --git a/webservice/app/controllers/permissions_controller.rb b/webservice/app/controllers/permissions_controller.rb
index d22cb8c..a1f8cc5 100644
--- a/webservice/app/controllers/permissions_controller.rb
+++ b/webservice/app/controllers/permissions_controller.rb
@@ -1,59 +1,110 @@
#
-#
+# Configure PolicyKit permissions for a user
#
+if __FILE__ == $0
+ require File.dirname(__FILE__) + '/../../test/test_helper'
+ puts "RAILS_ENV #{RAILS_ENV}"
+ puts "USER #{ENV['USER']}"
+ c = PermissionsController.new
+ c.test
+end
+
class PermissionsController < ApplicationController
before_filter :login_required
require "scr"
- private
-
- def get_permission_list(user_id, filter = nil)
+ def initialize
@permissions = []
- ret = Scr.instance.execute(["polkit-action"])
- return false unless ret && ret[:exit] == 0
+ end
+
+ private
+
+ #
+ # iterate over org.opensuse.yast permissions
+ # user_id: if set, iterate over granted perms
+ # else iterate over all
+ # filter: optional filter string, i.e. "scr"
+ #
+ def each_suse_permissions( user_id, filter = nil )
+ # filter org.opensuse.yast
+ suse_string = /org\.opensuse\.yast\..*/
- suse_string = "org.opensuse.yast."
- lines = ret[:stdout].split("\n") rescue []
+ # get users or all actions
+ ret = if user_id
+ Scr.instance.execute(["polkit-auth", "--user", user_id, "--explicit"])
+ else
+ Scr.instance.execute(["polkit-action"])
+ end rescue nil
+ raise RuntimeError unless ret && ret[:exit] == 0
- # a hash for mapping string 'permission name' => boolean 'granted'
- perms = Hash.new
-
- lines.each do |s|
- if (s.include?( suse_string )) &&
- (filter.blank? || s.include?( filter ))
- # set 'not granted' default
- perms[s] = false
- end
+ ret[:stdout].scan(suse_string) do |p|
+ next unless filter.blank? or p.include?(filter)
+ yield p
end
- ret = Scr.instance.execute(["polkit-auth", "--user", user_id, "--explicit"])
- return false unless ret && ret[:exit] == 0
+ end
+
+ #
+ # get all Array of Permissions user_id has
+ #
+
+ def permissions_list(user_id, filter = nil)
+
+ # a hash for mapping string 'permission name' => boolean 'granted'
+ perms = Hash.new
- lines = ret[:stdout].split("\n") rescue []
- lines.each do |s|
- # ignore the rights which do not have the prefix, do not have any .policy file
- # or do not match the filter
- if (s.include?( suse_string )) && perms.has_key?(s) && (filter.blank? || s.include?( filter ))
- # update the value to 'granted' state
- perms[s] = true
- end
- end
+ # get all known permissions into 'perms' hash
+ each_suse_permissions( nil, filter ) do |p|
+ perms[p] = false
+ end rescue return false
+
+ # now set those 'true' which are granted
+ each_suse_permissions( user_id, filter ) do |p|
+ perms[p] = true
+ end rescue return false
# convert the hash to a list of Permission objects
@permissions = []
- perms.each do |name,value|
- permission = Permission.new
- permission.name = name
- permission.grant = value
+ perms.each do |name,grant|
+ permission = Permission.new name, grant
@permissions << permission
end
+ true
end
-
+ #
+ # check if logged in user requests his own stuff
+ #
+ def user_self( params )
+ !params[:user_id].blank? && (params[:user_id] == self.current_account.login)
+ end
+
+ #
+ # check params and fill @permissions
+ #
+ def retrieve_permissions( params )
+ # user can always see his rights
+ unless permission_check( "org.opensuse.yast.permissions.read") || user_self(params)
+ render ErrorResult.error(403, 1, "no permission") and return
+ end
+ if params[:user_id].blank?
+ render ErrorResult.error(404, 2, "No user specified") and return
+ end
+ unless permissions_list(params[:user_id], params[:filter])
+ render ErrorResult.error(404, 2, "cannot get permission list") and return
+ end
+ true
+ end
+
public
+ # test for private functions
+ def test
+ permissions_list(ENV['USER']) if RAILS_ENV == "test"
+ end
+
#--------------------------------------------------------------------------------
#
# actions
@@ -65,42 +116,26 @@ class PermissionsController < ApplicationController
# GET /permissions.json?user_id=&filter=<filter>
def index
- # user can always see his rights
- unless (permission_check( "org.opensuse.yast.permissions.read") || (!params[:user_id].blank? && self.current_account.login == params[:user_id]))
- render ErrorResult.error(403, 1, "no permission") and return
- end
- if params[:user_id].blank?
- render ErrorResult.error(404, 2, "user_id is not defined") and return
- end
- unless get_permission_list(params[:user_id], params[:filter])
- render ErrorResult.error(404, 2, "cannot get permission list") and return
- end
+ retrieve_permissions params
end
# GET /users/<uid>/permissions/<id>?user_id=
def show
- unless (permission_check( "org.opensuse.yast.permissions.read") || (!params[:user_id].blank? && self.current_account.login == params[:user_id]))
- render ErrorResult.error(403, 1, "no permission") and return
- end
- if params[:user_id].blank?
- render ErrorResult.error(404, 2, "user_id is not defined") and return
- end
- if params[:id].blank?
- render ErrorResult.error(404, 2, "right is not defined") and return
- end
right = params[:id]
- @permission = Permission.new
- unless get_permission_list(params[:user_id])
- render ErrorResult.error(404, 1, "cannot get permission list") and return
+ if right.blank?
+ render ErrorResult.error(404, 2, "right is not defined") and return
end
- for i in 0..@permissions.size-1
- if @permissions[i].name == right
- permission = @permissions[i]
- break
- end
+
+ retrieve_permissions(params) or return
+
+ permission = nil
+ @permissions.each do |p|
+ next unless p.name == right
+ permission = p
+ break
end
- if !permission || permission.name.blank?
+ if permission.nil? || permission.name.blank?
render ErrorResult.error(404, 1, "Permission: #{right} not found.") and return
end
@@ -127,7 +162,8 @@ class PermissionsController < ApplicationController
render ErrorResult.error(404, 1, "no permissions found") and return
end
- ret = Scr.instance.execute(["polkit-auth", "--user", params[:permissions][:id], params[:permissions][:grant] ? "--grant" : "--revoke", params[:permissions][:name]])
+ ret = Scr.instance.execute(["polkit-auth", "--user", params[:id], params[:permissions][:grant] ? "--grant" : "--revoke", params[:permissions][:name]])
+
if ret[:exit] != 0
render ErrorResult.error(404, 1, ret[:stderr]) and return
end
diff --git a/webservice/app/models/permission.rb b/webservice/app/models/permission.rb
index 38de65a..a264e78 100644
--- a/webservice/app/models/permission.rb
+++ b/webservice/app/models/permission.rb
@@ -4,12 +4,11 @@
class Permission
- attr_accessor :name,
- :grant
+ attr_reader :name, :grant
- def initialize( permission_name = "", gr = false)
- @grant = gr
- @name = permission_name
+ def initialize( name = "", grant = false)
+ @grant = grant
+ @name = name
end
def to_xml( options = {} )
diff --git a/webservice/test/functional/permissions_controller_test.rb b/webservice/test/functional/permissions_controller_test.rb
index 0b1aca0..02594bc 100644
--- a/webservice/test/functional/permissions_controller_test.rb
+++ b/webservice/test/functional/permissions_controller_test.rb
@@ -22,7 +22,7 @@ class PermissionsControllerTest < ActionController::TestCase
@request.session[:account_id] = 1 # defined in fixtures
Scr.any_instance.stubs(:execute).with(["polkit-action"]).returns({:stderr=>"", :exit=>0, :stdout=>"org.opensuse.yast.system.users.read\norg.opensuse.yast.system.users.write\norg.opensuse.yast.system.users.new\norg.opensuse.yast.system.users.delete\n"})
- Scr.any_instance.stubs(:execute).with(["polkit-auth", "--user", "test_user", "--explicit"]).returns(:stderr=>"", :exit=>0, :stdout=>"org.opensuse.yast.system.users.read\norg.opensuse.yast.system.users.write\norg.opensuse.yast.system.users.new\n")
+ Scr.any_instance.stubs(:execute).with(["polkit-auth", "--user", "test_user", "--explicit"]).returns(:stderr=>"", :exit=>0, :stdout=>"org.opensuse.yast.system.users.read\norg.opensuse.yast.system.users.write\norg.opensuse.yast.system.users.new\norg.opensuse.yast.permissions.write\n")
Scr.any_instance.stubs(:execute).with(['polkit-auth', '--user', 'test_user', '--grant', 'org.opensuse.yast.patch.install']).returns({:stderr=>"", :exit=>0, :stdout=>""})
end
@@ -81,10 +81,21 @@ class PermissionsControllerTest < ActionController::TestCase
assert_response :success
end
+ test "permissions access no session" do
+ save = ENV['RAILS_ENV']
+ ENV['RAILS_ENV'] = "production" # do a real permission_check
+ uid = @request.session[:account_id]
+ @request.session[:account_id] = 0
+ get :show
+ @request.session[:account_id] = uid
+ ENV['RAILS_ENV'] = save
+ assert_response 401
+ end
+
test "permissions access show production" do
save = ENV['RAILS_ENV']
- ENV['RAILS_ENV'] = "production"
- get :show, :id => "org.opensuse.yast.system.users.read"
+ ENV['RAILS_ENV'] = "production" # do a real permission_check
+ get :show, :id => "org.opensuse.yast.system.read"
ENV['RAILS_ENV'] = save
assert_response 403
end
@@ -94,7 +105,7 @@ class PermissionsControllerTest < ActionController::TestCase
ENV['RAILS_ENV'] = "production"
get :show, :user_id => "nobody"
ENV['RAILS_ENV'] = save
- assert_response 403
+ assert_response 404
end
test "permissions access show without user" do
@@ -126,7 +137,7 @@ class PermissionsControllerTest < ActionController::TestCase
end
test "setting permissions without user" do
- put :update, :permissions => {"name"=>"org.opensuse.yast.patch.install", "id"=>"test_user", "grant"=>true}
+ put :update, :permissions => {"name"=>"org.opensuse.yast.patch.install", "grant"=>true}
assert_response 404
end
--
To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org
For additional commands, e-mail: yast-commit+help@opensuse.org