Skip to content

Commit

Permalink
Merge pull request #2956 from cyberark/allow-option-factory-inputs
Browse files Browse the repository at this point in the history
Allows option policy factory variable inputs
  • Loading branch information
jvanderhoof authored Sep 21, 2023
2 parents 51cae50 + 9603717 commit 7d7691c
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 15 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [1.20.0] - 2023-08-16

### Fixed
- Allow Factories with optional variables to save without error
[cyberark/conjur#2956](https://github.com/cyberark/conjur/pull/2956)
- OIDC authenticators support `https_proxy` and `HTTPS_PROXY` environment variables
[cyberark/conjur#2902](https://github.com/cyberark/conjur/pull/2902)
- Support plural syntax for revoke and deny
- Support plural syntax for revoke and deny
[cyberark/conjur#2901](https://github.com/cyberark/conjur/pull/2901)

### Added
Expand Down
12 changes: 8 additions & 4 deletions app/domain/factories/create_from_policy_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def initialize(renderer: Factories::Renderer.new, http: RestClient, schema_valid
@http = http
@schema_validator = schema_validator
@utilities = utilities
@logger = Rails.logger

# JSON and URI are defined here for visibility. They are not currently
# mocked in testing, thus, we're not setting them in the initializer.
Expand Down Expand Up @@ -128,6 +129,8 @@ def render_and_apply_policy(policy_load_path:, policy_template:, variables:, acc
template: policy_template,
variables: variables
).bind do |rendered_policy|
@logger.debug("Policy Factory is applying the following policy to '/policies/#{account}/policy/#{policy_load_path}'")
@logger.debug("\n#{rendered_policy}")
begin
response = @http.post(
"http://localhost:#{ENV['PORT']}/policies/#{account}/policy/#{policy_load_path}",
Expand Down Expand Up @@ -169,14 +172,15 @@ def render_and_apply_policy(policy_load_path:, policy_template:, variables:, acc
end

def set_factory_variables(schema_variables:, factory_variables:, variable_path:, authorization:, account:)
# Only set secrets defined in the policy
schema_variables.each_key do |factory_variable|
variable_id = @uri.encode_www_form_component("#{variable_path}/#{factory_variable}")
# Only set secrets defined in the policy and present in factory payload
(schema_variables.keys & factory_variables.keys).each do |schema_variable|

variable_id = @uri.encode_www_form_component("#{variable_path}/#{schema_variable}")
secret_path = "secrets/#{account}/variable/#{variable_id}"

@http.post(
"http://localhost:#{ENV['PORT']}/#{secret_path}",
factory_variables[factory_variable].to_s,
factory_variables[schema_variable].to_s,
{ 'Authorization' => authorization }
)
rescue RestClient::ExceptionWithResponse => e
Expand Down
2 changes: 1 addition & 1 deletion app/domain/factories/renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def initialize(render_engine: ERB)
end

def render(template:, variables:)
@success.new(@render_engine.new(template, nil, '-').result_with_hash(variables))
@success.new(@render_engine.new(template, trim_mode: '-').result_with_hash(variables))

# If variable in template is missing from variable list
rescue NameError => e
Expand Down
15 changes: 15 additions & 0 deletions app/domain/factories/templates/connections/v1/database.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ def policy_template
- !variable port
- !variable username
- !variable password
- !variable ssl-certificate
- !variable ssl-key
- !variable ssl-ca-certificate
- !group consumers
- !group administrators
Expand Down Expand Up @@ -89,6 +92,18 @@ def data
"description": "Database Password",
"type": "string"
},
"ssl-certificate": {
"description": "Client SSL Certificate",
"type": "string"
},
"ssl-key": {
"description": "Client SSL Key",
"type": "string"
},
"ssl-ca-certificate": {
"description": "CA Root Certificate",
"type": "string"
}
},
"required": %w[url port username password]
}
Expand Down
4 changes: 3 additions & 1 deletion dev/Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ RUN bundle
RUN find / -name httpclient -type d -exec find {} -name *.pem -type f -delete \;

RUN ln -sf /src/conjur-server/bin/conjurctl /usr/local/bin/
RUN rm /etc/service/syslog-ng/run

# Stop Syslog-NG from starting
# RUN touch /etc/service/syslog-ng/down

ENV PORT 3000
ENV TERM xterm
Expand Down
50 changes: 42 additions & 8 deletions spec/app/domain/factories/create_from_policy_factory_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@
)
end
let(:request) { { id: 'bar', branch: 'foo', variables: variables }.to_json }
let(:policy_body) { "- !policy\n id: bar\n annotations:\n factory: connections/v1/database\n \n body:\n - &variables\n - !variable url\n - !variable port\n - !variable username\n - !variable password\n - !variable ssl-certificate\n - !variable ssl-key\n - !variable ssl-ca-certificate\n\n - !group consumers\n - !group administrators\n\n # consumers can read and execute\n - !permit\n resource: *variables\n privileges: [ read, execute ]\n role: !group consumers\n\n # administrators can update (and read and execute, via role grant)\n - !permit\n resource: *variables\n privileges: [ update ]\n role: !group administrators\n\n # administrators has role consumers\n - !grant\n member: !group administrators\n role: !group consumers\n" }
context 'when request body is missing values' do
let(:variables) { { port: '1234', url: 'http://localhost', username: 'super-user' } }
it 'returns a failure response' do
Expand Down Expand Up @@ -208,7 +209,7 @@
allow(rest_client).to receive(:post)
.with(
"http://localhost:#{port}/policies/rspec/policy/foo",
"- !policy\n id: bar\n annotations:\n factory: connections/v1/database\n \n body:\n - &variables\n - !variable url\n - !variable port\n - !variable username\n - !variable password\n\n - !group consumers\n - !group administrators\n\n # consumers can read and execute\n - !permit\n resource: *variables\n privileges: [ read, execute ]\n role: !group consumers\n\n # administrators can update (and read and execute, via role grant)\n - !permit\n resource: *variables\n privileges: [ update ]\n role: !group administrators\n\n # administrators has role consumers\n - !grant\n member: !group administrators\n role: !group consumers\n",
policy_body,
{ 'Authorization' => 'foo-bar' }
).and_return(
double(RestClient::Response, code: 201, body: '{"created_roles":{},"version":13}')
Expand All @@ -227,14 +228,47 @@
expect(subject.success?).to be(true)
end
end
context 'when request body includes required and optional values' do
let(:variables) { { port: '1234', url: 'http://localhost', username: 'super-user', password: 'foo-bar', 'ssl-certificate': 'cert-body', 'ssl-key': 'cert-key-body' } }
it 'applies policy and relevant variables' do
allow(rest_client).to receive(:post)
.with(
"http://localhost:#{port}/policies/rspec/policy/foo",
policy_body,
{ 'Authorization' => 'foo-bar' }
).and_return(
double(RestClient::Response, code: 201, body: '{"created_roles":{},"version":13}')
)

variables.each do |variable, value|
allow(rest_client).to receive(:post)
.with(
"http://localhost:#{port}/secrets/rspec/variable/foo%2Fbar%2F#{variable}",
value,
{ 'Authorization' => 'foo-bar' }
).and_return(
double(RestClient::Response, code: 201, body: '')
)
end

expect(subject.success?).to be(true)

variables.each do |variable, value|
expect(rest_client).to have_received(:post).with(
"http://localhost:#{port}/secrets/rspec/variable/foo%2Fbar%2F#{variable}",
value,
{ 'Authorization' => 'foo-bar' }
)
end
end
end
context 'when request body includes extra variable values' do
let(:variables) { { foo: 'bar', port: '1234', url: 'http://localhost', username: 'super-user', password: 'foo-bar' } }
# let(:request) { { id: 'bar', branch: 'foo', variables: variables }.to_json }
it 'only saves variables defined in the factory' do
allow(rest_client).to receive(:post)
.with(
"http://localhost:#{port}/policies/rspec/policy/foo",
"- !policy\n id: bar\n annotations:\n factory: connections/v1/database\n \n body:\n - &variables\n - !variable url\n - !variable port\n - !variable username\n - !variable password\n\n - !group consumers\n - !group administrators\n\n # consumers can read and execute\n - !permit\n resource: *variables\n privileges: [ read, execute ]\n role: !group consumers\n\n # administrators can update (and read and execute, via role grant)\n - !permit\n resource: *variables\n privileges: [ update ]\n role: !group administrators\n\n # administrators has role consumers\n - !grant\n member: !group administrators\n role: !group consumers\n",
policy_body,
{ 'Authorization' => 'foo-bar' }
).and_return(
double(RestClient::Response, code: 201, body: '{"created_roles":{},"version":13}')
Expand All @@ -261,7 +295,7 @@
allow(rest_client).to receive(:post)
.with(
"http://localhost:#{port}/policies/rspec/policy/foo",
"- !policy\n id: bar\n annotations:\n factory: connections/v1/database\n \n body:\n - &variables\n - !variable url\n - !variable port\n - !variable username\n - !variable password\n\n - !group consumers\n - !group administrators\n\n # consumers can read and execute\n - !permit\n resource: *variables\n privileges: [ read, execute ]\n role: !group consumers\n\n # administrators can update (and read and execute, via role grant)\n - !permit\n resource: *variables\n privileges: [ update ]\n role: !group administrators\n\n # administrators has role consumers\n - !grant\n member: !group administrators\n role: !group consumers\n",
policy_body,
{ 'Authorization' => 'foo-bar' }
).and_return(
double(RestClient::Response, code: 201, body: '{"created_roles":{},"version":13}')
Expand All @@ -288,7 +322,7 @@
allow(rest_client).to receive(:post)
.with(
"http://localhost:#{port}/policies/rspec/policy/foo",
"- !policy\n id: bar\n annotations:\n factory: connections/v1/database\n \n body:\n - &variables\n - !variable url\n - !variable port\n - !variable username\n - !variable password\n\n - !group consumers\n - !group administrators\n\n # consumers can read and execute\n - !permit\n resource: *variables\n privileges: [ read, execute ]\n role: !group consumers\n\n # administrators can update (and read and execute, via role grant)\n - !permit\n resource: *variables\n privileges: [ update ]\n role: !group administrators\n\n # administrators has role consumers\n - !grant\n member: !group administrators\n role: !group consumers\n",
policy_body,
{ 'Authorization' => 'foo-bar' }
).and_return(
double(RestClient::Response, code: 201, body: '{"created_roles":{},"version":13}')
Expand All @@ -315,7 +349,7 @@
allow(rest_client).to receive(:post)
.with(
"http://localhost:#{port}/policies/rspec/policy/foo",
"- !policy\n id: bar\n annotations:\n factory: connections/v1/database\n \n body:\n - &variables\n - !variable url\n - !variable port\n - !variable username\n - !variable password\n\n - !group consumers\n - !group administrators\n\n # consumers can read and execute\n - !permit\n resource: *variables\n privileges: [ read, execute ]\n role: !group consumers\n\n # administrators can update (and read and execute, via role grant)\n - !permit\n resource: *variables\n privileges: [ update ]\n role: !group administrators\n\n # administrators has role consumers\n - !grant\n member: !group administrators\n role: !group consumers\n",
policy_body,
{ 'Authorization' => 'foo-bar' }
).and_return(
double(RestClient::Response, code: 201, body: '{"created_roles":{},"version":13}')
Expand All @@ -342,7 +376,7 @@
allow(rest_client).to receive(:post)
.with(
"http://localhost:#{port}/policies/rspec/policy/foo",
"- !policy\n id: bar\n annotations:\n factory: connections/v1/database\n \n body:\n - &variables\n - !variable url\n - !variable port\n - !variable username\n - !variable password\n\n - !group consumers\n - !group administrators\n\n # consumers can read and execute\n - !permit\n resource: *variables\n privileges: [ read, execute ]\n role: !group consumers\n\n # administrators can update (and read and execute, via role grant)\n - !permit\n resource: *variables\n privileges: [ update ]\n role: !group administrators\n\n # administrators has role consumers\n - !grant\n member: !group administrators\n role: !group consumers\n",
policy_body,
{ 'Authorization' => 'foo-bar' }
).and_return(
double(RestClient::Response, code: 201, body: '{"created_roles":{},"version":13}')
Expand All @@ -369,7 +403,7 @@
allow(rest_client).to receive(:post)
.with(
"http://localhost:#{port}/policies/rspec/policy/foo",
"- !policy\n id: bar\n annotations:\n factory: connections/v1/database\n \n body:\n - &variables\n - !variable url\n - !variable port\n - !variable username\n - !variable password\n\n - !group consumers\n - !group administrators\n\n # consumers can read and execute\n - !permit\n resource: *variables\n privileges: [ read, execute ]\n role: !group consumers\n\n # administrators can update (and read and execute, via role grant)\n - !permit\n resource: *variables\n privileges: [ update ]\n role: !group administrators\n\n # administrators has role consumers\n - !grant\n member: !group administrators\n role: !group consumers\n",
policy_body,
{ 'Authorization' => 'foo-bar' }
).and_return(
double(RestClient::Response, code: 201, body: '{"created_roles":{},"version":13}')
Expand Down

0 comments on commit 7d7691c

Please sign in to comment.