[Ovirt-devel] [PATCH server 05/10] PermissionController now uses the service layer
Scott Seago
sseago at redhat.com
Tue May 19 14:23:12 UTC 2009
Signed-off-by: Scott Seago <sseago at redhat.com>
---
src/app/controllers/permission_controller.rb | 129 +++++++++++---------------
src/app/models/permission.rb | 4 +
src/app/services/permission_service.rb | 102 ++++++++++++++++++++
3 files changed, 160 insertions(+), 75 deletions(-)
create mode 100644 src/app/services/permission_service.rb
diff --git a/src/app/controllers/permission_controller.rb b/src/app/controllers/permission_controller.rb
index d4c3fb5..55e7942 100644
--- a/src/app/controllers/permission_controller.rb
+++ b/src/app/controllers/permission_controller.rb
@@ -18,105 +18,84 @@
# also available at http://www.gnu.org/copyleft/gpl.html.
class PermissionController < ApplicationController
+ include PermissionService
# GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
verify :method => :post, :only => [ :destroy, :create ],
:redirect_to => { :controller => 'dashboard' }
- def redirect_to_parent
- redirect_to :controller => @permission.pool.get_controller, :action => 'show', :id => @permission.pool_id
- end
-
def show
- @permission = Permission.find(params[:id])
- set_perms(@permission.pool)
- authorize_action(Privilege::PERM_VIEW)
+ svc_show(params[:id])
end
def new
- @permission = Permission.new( { :pool_id => params[:pool_id]})
- @perms = @permission.pool.permissions
- @pool = Pool.find(params[:pool_id])
- filter = @pool.permissions.collect{ |permission| permission.uid }
- @users = Account.names(filter)
+ svc_new(params[:pool_id])
+ @users = Account.names(@permission.pool.permissions.collect{ |permission|
+ permission.uid })
@roles = Role.find(:all).collect{ |role| [role.name, role.id] }
- set_perms(@permission.pool)
- # admin permission required to view permissions
- if authorize_action(Privilege::PERM_SET)
- render :layout => 'popup'
- end
+ render :layout => 'popup'
end
def create
- @permission = Permission.new(params[:permission])
- set_perms(@permission.pool)
- if authorize_action(Privilege::PERM_SET)
- begin
- @permission.save_with_new_children
- render :json => { :object => "permission", :success => true,
- :alert => "created User Permissions for #{@permission.uid}." }
- rescue
- render :json => { :object => "permission", :success => false,
- :alert => "Error adding user: #{$!}" }
- end
- end
+ alert = svc_create(params[:permission])
+ render :json => { :object => "vm", :success => true, :alert => alert }
end
- #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[:role_id]
- permission_ids_str = params[:permission_ids]
- permission_ids = permission_ids_str.split(",").collect {|x| x.to_i}
-
- begin
- Permission.transaction do
- permissions = Permission.find(:all, :conditions => "id in (#{permission_ids.join(', ')})")
- permissions.each do |permission|
- permission.update_role(role) if permission.is_primary?
- end
+ permission_ids = params[:permission_ids].split(",")
+ role_id = params[:role_id]
+ successes = []
+ failures = {}
+ permission_ids.each do |permission_id|
+ begin
+ svc_update_role(permission_id, role_id)
+ successes << @permission
+ rescue PermissionError => perm_error
+ failures[@permission] = perm_error.message
+ rescue ActionError => ex
+ failures[@permission] = ex.message
+ rescue Exception => ex
+ failures[@permission] = ex.message
end
- render :json => { :object => "permission", :success => true,
- :alert => "User roles were successfully updated." }
- rescue
- render :json => { :object => "permission", :success => false,
- :alert => "Error updating user roles: #{$!}" }
end
+ unless failures.empty?
+ raise PartialSuccessError.new("Update roles for some Permission records",
+ failures, successes)
+ end
+ render :json => { :object => "permission", :success => true,
+ :alert => "Permission roles were successfully updated." }
end
- #FIXME: we need permissions checks. user must have permission. We also need to fail
- # for pools that aren't currently empty
def delete
- permission_ids_str = params[:permission_ids]
- permission_ids = permission_ids_str.split(",").collect {|x| x.to_i}
-
- begin
- Permission.transaction do
- permissions = Permission.find(:all, :conditions => "id in (#{permission_ids.join(', ')})")
- permissions.each do |permission|
- permission.destroy if permission.is_primary?
- end
+ permission_ids = params[:permission_ids].split(",")
+ successes = []
+ failures = {}
+ permission_ids.each do |permission_id|
+ begin
+ svc_destroy(permission_id)
+ successes << @permission
+ rescue PermissionError => perm_error
+ failures[@permission] = perm_error.message
+ rescue Exception => ex
+ failures[@permission] = ex.message
end
- render :json => { :object => "permission", :success => true,
- :alert => "User roles were successfully deleted." }
- rescue
- render :json => { :object => "permission", :success => false,
- :alert => "Error deleting user roles." }
end
+ unless failures.empty?
+ raise PartialSuccessError.new("Delete failed for some Permission records",
+ failures, successes)
+ end
+ render :json => { :object => "permission", :success => true,
+ :alert => "Permission records were successfully deleted." }
end
def destroy
- @permission = Permission.find(params[:id])
- set_perms(@permission.pool)
- if authorize_action(Privilege::PERM_SET)
- pool = @permission.pool
- if @permission.destroy
- if pool
- flash[:notice] = "<strong>#{@permission.uid}</strong> permissions were revoked successfully"
- redirect_to :controller => pool.get_controller, :action => 'show', :id => pool.id
- else
- redirect_to :controller => 'dashboard', :action => 'list'
- end
- end
- end
+ alert = svc_destroy(params[:id])
+ render :json => { :object => "vm", :success => true, :alert => alert }
+ end
+
+ # FIXME: remove these when service transition is complete. these are here
+ # to keep from running permissions checks and other setup steps twice
+ def tmp_pre_update
+ end
+ def tmp_authorize_admin
end
end
diff --git a/src/app/models/permission.rb b/src/app/models/permission.rb
index 2567b08..f74a11a 100644
--- a/src/app/models/permission.rb
+++ b/src/app/models/permission.rb
@@ -50,7 +50,10 @@ class Permission < ActiveRecord::Base
def grid_id
id.to_s + "_" + (is_primary? ? "1" : "0")
end
+ # only update role for primary permissions, return false (and do nothing)
+ # for inherited permissions
def update_role(new_role)
+ return false unless is_primary?
self.transaction do
self.role_id = new_role
self.save!
@@ -59,6 +62,7 @@ class Permission < ActiveRecord::Base
permission.save!
end
end
+ true
end
def save_with_new_children
self.transaction do
diff --git a/src/app/services/permission_service.rb b/src/app/services/permission_service.rb
new file mode 100644
index 0000000..2e02a69
--- /dev/null
+++ b/src/app/services/permission_service.rb
@@ -0,0 +1,102 @@
+#
+# Copyright (C) 2009 Red Hat, Inc.
+# Written by Scott Seago <sseago at redhat.com>,
+# David Lutterkort <lutter 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.
+# Mid-level API: Business logic around individual permissions
+module PermissionService
+
+ include ApplicationService
+
+ # Load the Permission with +id+ for viewing
+ #
+ # === Instance variables
+ # [<tt>@permission</tt>] stores the Permission with +id+
+ # === Required permissions
+ # [<tt>Privilege::PERM_VIEW</tt>] on permission's Pool
+ def svc_show(id)
+ lookup(id,Privilege::PERM_VIEW)
+ end
+
+ # Load the Permission with +id+ for editing
+ #
+ # === Instance variables
+ # [<tt>@permission</tt>] stores the Permission with +id+
+ # === Required permissions
+ # [<tt>Privilege::PERM_SET</tt>] on permission's Pool
+ def svc_modify(id)
+ lookup(id,Privilege::PERM_SET)
+ end
+
+ # Load a new Permission for creating
+ #
+ # === Instance variables
+ # [<tt>@permission</tt>] loads a new Permission object into memory
+ # === Required permissions
+ # [<tt>Privilege::PERM_SET</tt>] for the permission's Pool as specified by
+ # +pool_id+
+ def svc_new(pool_id)
+ @permission = Permission.new( { :pool_id => pool_id})
+ authorized!(Privilege::PERM_SET, at permission.pool)
+ end
+
+ # Save a new Permission record
+ #
+ # === Instance variables
+ # [<tt>@permission</tt>] the newly saved Permission record
+ # === Required permissions
+ # [<tt>Privilege::PERM_SET</tt>] for the permission's Pool
+ def svc_create(perm_hash)
+ @permission = Permission.new(perm_hash)
+ authorized!(Privilege::PERM_SET, @permission.pool)
+ @permission.save_with_new_children
+ return "created User Permissions for #{@permission.uid}."
+ end
+
+ # Destroys for the Permission with +id+
+ #
+ # === Instance variables
+ # [<tt>@permission</tt>] stores the Permission with +id+
+ # === Required permissions
+ # [<tt>Privilege::PERM_SET</tt>] for the Permission's Pool
+ def svc_destroy(id)
+ lookup(id,Privilege::PERM_SET)
+ @permission.destroy
+ return "Permission record was successfully deleted."
+ end
+
+ # Updates the role for a user permission.
+ #
+ # === Instance variables
+ # [<tt>@permission</tt>] stores the Permission with +id+
+ # === Required permissions
+ # [<tt>Privilege::PERM_SET</tt>] for the Permission's Pool
+ def svc_update_role(id, role_id)
+ lookup(id,Privilege::PERM_SET)
+ unless @permission.update_role(role_id)
+ raise ActionError.new("Inherited permissions cannot be modified directly.")
+ end
+ return "User Role updated for permission record"
+ end
+
+ private
+ def lookup(id, priv)
+ @permission = Permission.find(id)
+ authorized!(priv, at permission.pool)
+ end
+
+end
--
1.6.0.6
More information about the ovirt-devel
mailing list