Project

General

Profile

« Previous | Next » 

Revision 8813aee5

Added by Ondřej Pražák about 7 years ago

Fixes #18317 - Clone user role via API

View differences:

app/controllers/api/v2/roles_controller.rb
include Foreman::Controller::Parameters::Role
before_action :find_optional_nested_object
before_action :find_resource, :only => %w{show update destroy}
before_action :find_resource, :only => %w{show update destroy clone}
api :GET, "/roles/", N_("List all roles")
param_group :search_and_pagination, ::Api::V2::BaseController
......
def_param_group :role do
param :role, Hash, :required => true, :action_aware => true do
param :name, String, :required => true
param :description, String, :desc => N_('Role description')
param_group :taxonomies, ::Api::V2::BaseController
end
end
......
process_response @role.destroy
end
api :POST, "/roles/:id/clone", N_("Clone a role")
param :id, String, :required => true
param_group :role
def clone
@role = @role.clone(role_params)
process_response @role.save
end
private
def allowed_nested_id
%w(user_id)
end
def action_permission
case params[:action]
when 'clone'
:create
else
super
end
end
end
end
end
app/controllers/roles_controller.rb
def role_from_form
if cloning?
new_role = Role.find(params[:original_role_id]).
deep_clone(:include => [:filters => :filterings])
new_role = Role.find(params[:original_role_id]).clone
new_role.name = params[:role][:name]
new_role.organization_ids = params[:role][:organization_ids]
new_role.location_ids = params[:role][:location_ids]
app/models/role.rb
friendly_id :name
include Parameterizable::ByIdName
# Built-in roles
BUILTIN_DEFAULT_ROLE = 2
audited
......
self.filters.where(:override => true).map { |filter| filter.disable_overriding! }
end
def clone(role_params = {})
new_role = self.deep_clone(:except => [:name, :builtin],
:include => [:locations, :organizations, { :filters => :permissions }])
new_role.attributes = role_params
new_role
end
private
def sync_inheriting_filters
app/services/foreman/access_permissions.rb
map.permission :view_roles, {:roles => [:index, :auto_complete_search],
:'api/v2/roles' => [:index, :show]}
map.permission :create_roles, {:roles => [:new, :create, :clone],
:'api/v2/roles' => [:create]}
:'api/v2/roles' => [:create, :clone]}
map.permission :edit_roles, {:roles => [:edit, :update, :disable_filters_overriding],
:'api/v2/roles' => [:update]}
map.permission :destroy_roles, {:roles => [:destroy],
config/routes/api/v2.rb
(resources :organizations, :only => [:index, :show]) if SETTINGS[:organizations_enabled]
end
resources :users, :except => [:new, :edit]
member do
post :clone
end
end
resources :permissions, :only => [:index, :show] do
collection do
test/controllers/api/v2/roles_controller_test.rb
end
assert_response :success
end
test "should clone role and its permissions" do
new_name = "New Manager"
manager = Role.find_by :name => "Manager"
perm_count = manager.permissions.count
post :clone, { :name => "New Manager", :id => manager.id }
assert_response :success
r = Role.find_by :name => new_name
assert_equal perm_count, r.permissions.count
end
test "should clone role and its taxonomies" do
new_name = "New Role"
loc = Location.first
org = Organization.first
role = FactoryGirl.create(:role, :name => "Test Role", :locations => [loc], :organizations => [org])
post :clone, { :id => role.id, :role => { :name => new_name } }
assert_response :success
r = Role.find_by :name => new_name
assert_equal 1, r.organizations.count
assert_equal 1, r.locations.count
assert_equal org, r.organizations.first
assert_equal loc, r.locations.first
end
test "should override attributes when clonning" do
new_name = "New Role"
loc = taxonomies(:location1)
org = taxonomies(:organization1)
desc = "default description"
new_org = taxonomies(:organization2)
new_loc = taxonomies(:location2)
new_desc = "updated description"
new_role = { :description => new_desc, :location_ids => [new_loc.id], :organization_ids => [new_org.id], :name => new_name }
role = FactoryGirl.create(:role, :name => "Test Role", :locations => [loc], :organizations => [org], :description => desc)
post :clone, { :new_name => new_name,
:id => role.id,
:role => new_role }
assert_response :success
cloned_role = Role.find_by :name => new_name
assert cloned_role
assert_equal new_org, cloned_role.organizations.first
assert_equal new_loc, cloned_role.locations.first
assert_equal new_desc, cloned_role.description
end
test "should override organizations and leave locations alone when clonning" do
new_name = "New Role"
loc = taxonomies(:location1)
org = taxonomies(:organization1)
desc = "default description"
new_org = taxonomies(:organization2)
new_desc = "updated description"
new_role = { :description => new_desc, :organization_ids => [new_org.id], :name => new_name }
role = FactoryGirl.create(:role, :name => "Test Role", :locations => [loc], :organizations => [org], :description => desc)
post :clone, { :new_name => new_name,
:id => role.id,
:role => new_role }
assert_response :success
cloned_role = Role.find_by :name => new_name
assert cloned_role
assert_equal new_org, cloned_role.organizations.first
assert_equal loc, cloned_role.locations.first
assert_equal new_desc, cloned_role.description
end
test "should not have any taxonomies when clonning" do
new_name = "New Role"
loc = taxonomies(:location1)
org = taxonomies(:organization1)
desc = "default description"
new_role = { :location_ids => [], :organization_ids => [], :name => new_name }
role = FactoryGirl.create(:role, :name => "Test Role", :locations => [loc], :organizations => [org], :description => desc)
post :clone, { :new_name => new_name,
:id => role.id,
:role => new_role }
assert_response :success
cloned_role = Role.find_by :name => new_name
assert cloned_role
assert_equal [], cloned_role.organizations
assert_equal [], cloned_role.locations
end
end
test/factories/user_related.rb
factory :role do
sequence(:name) {|n| "role #{n}" }
locations []
organizations []
builtin 0
end

Also available in: Unified diff