Skip to content

Commit

Permalink
Add auths to script payload join table
Browse files Browse the repository at this point in the history
Automatically add authentications referenced in the credentials payload
to the authentications_configuration_script_payload join table
  • Loading branch information
agrare committed Aug 3, 2023
1 parent c46a8ce commit 75bbc75
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
25 changes: 25 additions & 0 deletions app/controllers/api/configuration_script_payloads_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,31 @@ def edit_resource(type, id, data)
unpermitted_params = data.keys.map(&:to_s) - allowed_params
raise BadRequestError, _("Invalid parameters: %{params}" % {:params => unpermitted_params.join(", ")}) if unpermitted_params.any?

# If a credentials payload is provided, map any requested authentication
# records to the configuration_script_payload via the
# authentications_configuration_script_payloads join table.
unless data["credentials"].nil?
# Credentials can be a static string or a payload with an external
# Authentication record referenced by credential_ref and credential_field.
credential_refs = data["credentials"].values.select { |val| val.kind_of?(Hash) }.pluck("credential_ref")
# Lookup the Authentication record by ems_ref in the parent manager's
# list of authentications.
credentials = resource.manager&.authentications&.where(:ems_ref => credential_refs) || []
# Filter the collection based on the current user's RBAC roles.
credentials, _ = collection_filterer(credentials, "authentications", ::Authentication)
# If any requested authentications were unable to be found, either due
# to a bad credential_ref or due to RBAC then raise a 400 BadRequestError.
missing_credential_refs = credential_refs - credentials.pluck(:ems_ref)
if missing_credential_refs.any?
raise BadRequestError,
_("Could not find credentials %{missing_credential_refs}") %
{:missing_credential_refs => missing_credential_refs}
end
# Reset the authentications collection with the current set of credentials.
# This will also remove any credential references not in the new payload.
resource.authentications = credentials
end

resource.update!(data.except(*ID_ATTRS))
resource
end
Expand Down
39 changes: 38 additions & 1 deletion spec/requests/configuration_script_payloads_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
end

describe 'POST /api/configuration_script_payloads' do
let(:script_payload) { FactoryBot.create(:configuration_script_payload) }
let(:manager) { FactoryBot.create(:ext_management_system) }
let(:script_payload) { FactoryBot.create(:configuration_script_payload, :manager => manager) }

context "edit" do
it 'forbids edit of a configuration_script_payload without an appropriate role' do
Expand All @@ -71,6 +72,42 @@
expect(script_payload.credentials).to include("my-cred" => "credential123")
end

it "fails if the credential can't be found" do
api_basic_authorize collection_action_identifier(:configuration_script_payloads, :edit, :post)

post(api_configuration_script_payloads_url, :params => {:action => 'edit', :resources => [{:id => script_payload.id, :name => 'foo', :credentials => {"my-cred" => {"credential_ref" => "my-credential", "credential_field" => "userid"}}}]})
expect(response).to have_http_status(:bad_request)
end

context "with an authentication reference in credentials" do
let!(:authentication) { FactoryBot.create(:authentication, :ems_ref => "my-credential", :resource => manager) }

it "adds the authentication to the configuration_script_payload.authentications" do
api_basic_authorize collection_action_identifier(:configuration_script_payloads, :edit, :post)

post(api_configuration_script_payloads_url, :params => {:action => 'edit', :resources => [{:id => script_payload.id, :name => 'foo', :credentials => {"my-cred" => {"credential_ref" => "my-credential", "credential_field" => "userid"}}}]})
expect(script_payload.reload.authentications).to include(authentication)
end

context "with an existing associated authentication record" do
before { script_payload.authentications << authentication }

it "doesn't duplicate records" do
api_basic_authorize collection_action_identifier(:configuration_script_payloads, :edit, :post)

post(api_configuration_script_payloads_url, :params => {:action => 'edit', :resources => [{:id => script_payload.id, :name => 'foo', :credentials => {"my-cred" => {"credential_ref" => "my-credential", "credential_field" => "userid"}}}]})
expect(script_payload.reload.authentications.count).to eq(1)
end

it "removes associated authentications" do
api_basic_authorize collection_action_identifier(:configuration_script_payloads, :edit, :post)

post(api_configuration_script_payloads_url, :params => {:action => 'edit', :resources => [{:id => script_payload.id, :name => 'foo', :credentials => {}}]})
expect(script_payload.reload.authentications.count).to be_zero
end
end
end

context "with a configuration_script_source" do
let(:script_source) { FactoryBot.create(:configuration_script_source) }
let(:script_payload) { FactoryBot.create(:configuration_script_payload, :configuration_script_source => script_source) }
Expand Down

0 comments on commit 75bbc75

Please sign in to comment.