conjur-api 5.3.8.pre.194 → 5.4.0.pre.341

Sign up to get free protection for your applications and to get access to all the features.
data/docker-compose.yml CHANGED
@@ -4,15 +4,36 @@ services:
4
4
  image: postgres:9.3
5
5
 
6
6
  conjur_5:
7
- image: cyberark/conjur
7
+ image: cyberark/conjur:edge
8
8
  command: server -a cucumber
9
9
  environment:
10
10
  DATABASE_URL: postgres://postgres@pg/postgres
11
11
  CONJUR_DATA_KEY: 'WMfApcDBtocRWV+ZSUP3Tjr5XNU+Z2FdBb6BEezejIs='
12
12
  volumes:
13
13
  - authn_local_5:/run/authn-local
14
+ - ./ci/oauth/keycloak:/scripts
14
15
  depends_on:
15
16
  - pg
17
+ - keycloak
18
+
19
+ keycloak:
20
+ image: jboss/keycloak:4.3.0.Final
21
+ environment:
22
+ - KEYCLOAK_USER=admin
23
+ - KEYCLOAK_PASSWORD=admin
24
+ - KEYCLOAK_APP_USER=alice
25
+ - KEYCLOAK_APP_USER_PASSWORD=alice
26
+ - KEYCLOAK_APP_USER_EMAIL=alice@conjur.net
27
+ - DB_VENDOR=H2
28
+ - KEYCLOAK_CLIENT_ID=conjurClient
29
+ - KEYCLOAK_REDIRECT_URI=http://conjur_5/authn-oidc/keycloak/cucumber/authenticate
30
+ - KEYCLOAK_CLIENT_SECRET=1234
31
+ - KEYCLOAK_SCOPE=openid
32
+ ports:
33
+ - "7777:8080"
34
+ volumes:
35
+ - ./ci/oauth/keycloak/standalone.xml:/opt/jboss/keycloak/standalone/configuration/standalone.xml
36
+ - ./ci/oauth/keycloak:/scripts
16
37
 
17
38
  conjur_4:
18
39
  image: registry2.itci.conjur.net/conjur-appliance-cuke-master:4.9-stable
@@ -33,6 +54,7 @@ services:
33
54
  - ./features/reports:/src/conjur-api/features/reports
34
55
  - ./coverage:/src/conjur-api/coverage
35
56
  - authn_local_5:/run/authn-local-5
57
+ - ./ci/oauth/keycloak:/scripts
36
58
  environment:
37
59
  CONJUR_APPLIANCE_URL: http://conjur_5
38
60
  CONJUR_VERSION: 5
@@ -7,6 +7,7 @@ Feature: List and manage authenticators
7
7
  - !webservice conjur/authn-k8s/my-auth
8
8
  POLICY
9
9
  """
10
+ And I setup a keycloak authenticator
10
11
 
11
12
  Scenario: Authenticator list includes the authenticator status
12
13
  When I run the code:
@@ -31,3 +32,10 @@ Feature: List and manage authenticators
31
32
  $conjur.authenticator_list
32
33
  """
33
34
  Then the JSON at "enabled" should be ["authn"]
35
+
36
+ Scenario: Get a list of OIDC providers
37
+ When I run the code:
38
+ """
39
+ $conjur.authentication_providers("authn-oidc")
40
+ """
41
+ Then the providers list contains service id "keycloak"
@@ -0,0 +1,14 @@
1
+ Feature: Authenticate with Conjur
2
+
3
+ Background:
4
+ Given I setup a keycloak authenticator
5
+
6
+ Scenario: Authenticate with OIDC state and code
7
+ When I retrieve the login url for OIDC authenticator "keycloak"
8
+ And I retrieve auth info for the OIDC provider with username: "alice" and password: "alice"
9
+ And I run the code:
10
+ """
11
+ $conjur.authenticator_enable "authn-oidc", "keycloak"
12
+ Conjur::API.authenticator_authenticate("authn-oidc", "keycloak", options: @auth_body)
13
+ """
14
+ Then the JSON should have "payload"
@@ -16,3 +16,37 @@ Then(/^this code should fail with "([^"]*)"$/) do |error_msg, code|
16
16
  fail "The provided block did not raise an error"
17
17
  end
18
18
  end
19
+
20
+ Given(/^I retrieve the login url for OIDC authenticator "([^"]+)"$/) do |service_id|
21
+ provider = $conjur.authentication_providers("authn-oidc").select {|provider_details| provider_details["service_id"] == service_id}
22
+ @login_url = provider[0]["redirect_uri"]
23
+ puts @login_url
24
+ end
25
+
26
+ Given(/^I retrieve auth info for the OIDC provider with username: "([^"]+)" and password: "([^"]+)"$/) do |username, password|
27
+ res = Net::HTTP.get_response(URI(@login_url))
28
+ raise res if res.is_a?(Net::HTTPError) || res.is_a?(Net::HTTPClientError)
29
+
30
+ all_cookies = res.get_fields('set-cookie')
31
+ puts all_cookies
32
+ cookies_arrays = Array.new
33
+ all_cookies.each do |cookie|
34
+ cookies_arrays.push(cookie.split('; ')[0])
35
+ end
36
+
37
+ html = Nokogiri::HTML(res.body)
38
+ post_uri = URI(html.xpath('//form').first.attributes['action'].value)
39
+
40
+ http = Net::HTTP.new(post_uri.host, post_uri.port)
41
+ http.use_ssl = true
42
+ request = Net::HTTP::Post.new(post_uri.request_uri)
43
+ request['Cookie'] = cookies_arrays.join('; ')
44
+ request.set_form_data({'username' => username, 'password' => password})
45
+
46
+ response = http.request(request)
47
+
48
+ if response.is_a?(Net::HTTPRedirection)
49
+ response_details = URI.decode_www_form(URI(response['location']).query)
50
+ @auth_body = {state: response_details.assoc('state')[1], code: response_details.assoc('code')[1]}
51
+ end
52
+ end
@@ -13,6 +13,15 @@ Given(/^a new user$/) do
13
13
  expect(@user_api_key).to be
14
14
  end
15
15
 
16
+ Given(/^a user "([^"]+)"$/) do |user_id|
17
+ response = $conjur.load_policy 'root', <<-POLICY
18
+ - !user #{user_id}
19
+ POLICY
20
+ @user = $conjur.resource("cucumber:user:#{user_id}")
21
+ @user_api_key = response.created_roles["cucumber:user:#{user_id}"]['api_key']
22
+ expect(@user_api_key).to be
23
+ end
24
+
16
25
  Given(/^a new delegated user$/) do
17
26
  # Create a new host that is owned by that user
18
27
  step 'a new user'
@@ -73,3 +82,53 @@ Given(/^a new delegated host$/) do
73
82
  @host = $conjur.resource("cucumber:host:#{@host_id}")
74
83
  @host.attributes['api_key'] = @host_api_key
75
84
  end
85
+
86
+ Given(/^I setup a keycloak authenticator$/) do
87
+ $conjur.load_policy 'root', <<-POLICY
88
+ - !policy
89
+ id: conjur/authn-oidc/keycloak
90
+ body:
91
+ - !webservice
92
+
93
+ - !variable provider-uri
94
+ - !variable client-id
95
+ - !variable client-secret
96
+ - !variable name
97
+
98
+ - !variable claim-mapping
99
+
100
+ - !variable nonce
101
+ - !variable state
102
+
103
+ - !variable redirect-uri
104
+
105
+ - !group users
106
+
107
+ - !permit
108
+ role: !group users
109
+ privilege: [ read, authenticate ]
110
+ resource: !webservice
111
+
112
+ - !user alice
113
+ - !grant
114
+ role: !group conjur/authn-oidc/keycloak/users
115
+ member: !user alice
116
+ POLICY
117
+ @provider_uri = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/provider-uri")
118
+ @client_id = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/client-id")
119
+ @client_secret = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/client-secret")
120
+ @name = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/name")
121
+ @claim_mapping = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/claim-mapping")
122
+ @nonce = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/nonce")
123
+ @state = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/state")
124
+ @redirect_uri = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/redirect-uri")
125
+
126
+ @provider_uri.add_value "https://keycloak:8443/auth/realms/master"
127
+ @client_id.add_value "conjurClient"
128
+ @client_secret.add_value "1234"
129
+ @claim_mapping.add_value "preferred_username"
130
+ @nonce.add_value SecureRandom.uuid
131
+ @state.add_value SecureRandom.uuid
132
+ @name.add_value "keycloak"
133
+ @redirect_uri.add_value "http://conjur_5/authn-oidc/keycloak/cucumber/authenticate"
134
+ end
@@ -5,3 +5,7 @@ end
5
5
  Then(/^the result should be the public key$/) do
6
6
  expect(@result).to eq(@public_key + "\n")
7
7
  end
8
+
9
+ Then(/^the providers list contains service id "([^"]+)"$/) do |service_id|
10
+ expect(@result.map{ |x| x["service_id"]}).to include(service_id)
11
+ end
@@ -1,4 +1,5 @@
1
1
  require 'simplecov'
2
+ require 'nokogiri'
2
3
 
3
4
  SimpleCov.start do
4
5
  command_name "#{ENV['RUBY_VERSION']}"
@@ -13,6 +13,14 @@ module Conjur
13
13
  JSON.parse(url_for(:authenticators).get)
14
14
  end
15
15
 
16
+ # Fetches the available authentication providers for the authenticator and account.
17
+ # The authenticators must be loaded in Conjur policy prior to fetching.
18
+ #
19
+ # @param [String] authenticator the authenticator type to retrieve providers for
20
+ def authentication_providers authenticator, account: Conjur.configuration.account
21
+ JSON.parse(url_for(:authentication_providers, account, authenticator, credentials).get)
22
+ end
23
+
16
24
  # Enables an authenticator in Conjur. The authenticator must be defined and
17
25
  # loaded in Conjur policy prior to enabling it.
18
26
  #
@@ -22,6 +22,10 @@ require 'conjur/user'
22
22
 
23
23
  module Conjur
24
24
  class API
25
+ def whoami
26
+ JSON.parse(url_for(:whoami, credentials).get)
27
+ end
28
+
25
29
  class << self
26
30
  #@!group Authentication
27
31
 
@@ -50,6 +54,21 @@ module Conjur
50
54
  url_for(:authn_login, account, username, password).get
51
55
  end
52
56
 
57
+ # Authenticates using a third party authenticator like authn-oidc. It will return an
58
+ # access token to be used to authenticate further API calls.
59
+ #
60
+ # @param [String] authenticator
61
+ # @param [String] service_id
62
+ # @param [String] account The organization account.
63
+ # @param [Hash] params Additional params to send to authenticator
64
+ # @return [String] A JSON formatted authentication token.
65
+ def authenticator_authenticate authenticator, service_id, account: Conjur.configuration.account, options: {}
66
+ if Conjur.log
67
+ Conjur.log << "Authenticating to account #{account} using #{authenticator}/#{service_id}\n"
68
+ end
69
+ JSON.parse url_for(:authenticator_authenticate, account, service_id, authenticator, options).get
70
+ end
71
+
53
72
  # Exchanges Conjur the API key (refresh token) for an access token. The access token can
54
73
  # then be used to authenticate further API calls.
55
74
  #
@@ -43,6 +43,13 @@ module Conjur
43
43
  )[fully_escape account][fully_escape username]['authenticate']
44
44
  end
45
45
 
46
+ def authenticator_authenticate(account, service_id, authenticator, options)
47
+ RestClient::Resource.new(
48
+ Conjur.configuration.core_url,
49
+ Conjur.configuration.rest_client_options
50
+ )[fully_escape authenticator][fully_escape service_id][fully_escape account]['authenticate'][options_querystring options]
51
+ end
52
+
46
53
  def authenticator account, authenticator, service_id, credentials
47
54
  RestClient::Resource.new(
48
55
  Conjur.configuration.core_url,
@@ -57,6 +64,13 @@ module Conjur
57
64
  )['authenticators']
58
65
  end
59
66
 
67
+ def authentication_providers(account, authenticator, credentials)
68
+ RestClient::Resource.new(
69
+ Conjur.configuration.core_url,
70
+ Conjur.configuration.create_rest_client_options(credentials)
71
+ )[fully_escape authenticator][fully_escape account]['providers']
72
+ end
73
+
60
74
  # For v5, the authn-local message is a JSON string with account, sub, and optional fields.
61
75
  def authn_authenticate_local username, account, expiration, cidr, &block
62
76
  { account: account, sub: username }.tap do |params|
@@ -236,6 +250,13 @@ module Conjur
236
250
  )['ldap-sync']["policy?config_name=#{fully_escape(config_name)}"]
237
251
  end
238
252
 
253
+ def whoami(credentials)
254
+ RestClient::Resource.new(
255
+ Conjur.configuration.core_url,
256
+ Conjur.configuration.create_rest_client_options(credentials)
257
+ )['whoami']
258
+ end
259
+
239
260
  private
240
261
 
241
262
  def resource_annotations resource
data/test.sh CHANGED
@@ -4,6 +4,7 @@
4
4
  # My local RUBY_VERSION is set to ruby-#.#.# so this allows running locally.
5
5
  RUBY_VERSION="$(cut -d '-' -f 2 <<< "$RUBY_VERSION")"
6
6
 
7
+ source ./ci/oauth/keycloak/keycloak_functions.sh
7
8
 
8
9
  function finish {
9
10
  echo 'Removing test environment'
@@ -54,7 +55,9 @@ function runTests_5() {
54
55
  echo '-----'
55
56
  docker-compose run --rm \
56
57
  -e CONJUR_AUTHN_API_KEY="$api_key" \
57
- tester_5 rake jenkins_init jenkins_spec jenkins_cucumber_v5
58
+ -e SSL_CERT_FILE=/etc/ssl/certs/keycloak.pem \
59
+ tester_5 \
60
+ "/scripts/fetch_certificate && rake jenkins_init jenkins_spec jenkins_cucumber_v5"
58
61
  }
59
62
 
60
63
  function runTests_4() {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: conjur-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.3.8.pre.194
4
+ version: 5.4.0.pre.341
5
5
  platform: ruby
6
6
  authors:
7
7
  - CyberArk Maintainers
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-31 00:00:00.000000000 Z
11
+ date: 2022-08-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -226,6 +226,20 @@ dependencies:
226
226
  - - ">="
227
227
  - !ruby/object:Gem::Version
228
228
  version: '0'
229
+ - !ruby/object:Gem::Dependency
230
+ name: nokogiri
231
+ requirement: !ruby/object:Gem::Requirement
232
+ requirements:
233
+ - - ">="
234
+ - !ruby/object:Gem::Version
235
+ version: '0'
236
+ type: :development
237
+ prerelease: false
238
+ version_requirements: !ruby/object:Gem::Requirement
239
+ requirements:
240
+ - - ">="
241
+ - !ruby/object:Gem::Version
242
+ version: '0'
229
243
  description: Conjur API
230
244
  email:
231
245
  - conj_maintainers@cyberark.com
@@ -257,6 +271,12 @@ files:
257
271
  - bin/parse-changelog.sh
258
272
  - ci/configure_v4.sh
259
273
  - ci/configure_v5.sh
274
+ - ci/oauth/keycloak/create_client
275
+ - ci/oauth/keycloak/create_user
276
+ - ci/oauth/keycloak/fetch_certificate
277
+ - ci/oauth/keycloak/keycloak_functions.sh
278
+ - ci/oauth/keycloak/standalone.xml
279
+ - ci/oauth/keycloak/wait_for_server
260
280
  - ci/submit-coverage
261
281
  - conjur-api.gemspec
262
282
  - dev/Dockerfile.dev
@@ -267,6 +287,7 @@ files:
267
287
  - example/demo_v4.rb
268
288
  - example/demo_v5.rb
269
289
  - features/authenticators.feature
290
+ - features/authn.feature
270
291
  - features/authn_local.feature
271
292
  - features/exists.feature
272
293
  - features/group.feature
@@ -378,7 +399,7 @@ homepage: https://github.com/cyberark/conjur-api-ruby/
378
399
  licenses:
379
400
  - Apache-2.0
380
401
  metadata: {}
381
- post_install_message:
402
+ post_install_message:
382
403
  rdoc_options: []
383
404
  require_paths:
384
405
  - lib
@@ -393,13 +414,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
393
414
  - !ruby/object:Gem::Version
394
415
  version: 1.3.1
395
416
  requirements: []
396
- rubyforge_project:
397
- rubygems_version: 2.7.6.2
398
- signing_key:
417
+ rubygems_version: 3.2.33
418
+ signing_key:
399
419
  specification_version: 4
400
420
  summary: Conjur API
401
421
  test_files:
402
422
  - features/authenticators.feature
423
+ - features/authn.feature
403
424
  - features/authn_local.feature
404
425
  - features/exists.feature
405
426
  - features/group.feature