conjur-api 5.3.8.pre.319 → 5.3.8.pre.321

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +10 -0
  3. data/.dockerignore +1 -0
  4. data/.github/CODEOWNERS +10 -0
  5. data/.gitignore +32 -0
  6. data/.gitleaks.toml +219 -0
  7. data/.overcommit.yml +16 -0
  8. data/.project +18 -0
  9. data/.rubocop.yml +3 -0
  10. data/.rubocop_settings.yml +86 -0
  11. data/.rubocop_todo.yml +709 -0
  12. data/.yardopts +1 -0
  13. data/CHANGELOG.md +448 -0
  14. data/CONTRIBUTING.md +138 -0
  15. data/Dockerfile +16 -0
  16. data/Gemfile +7 -0
  17. data/Jenkinsfile +136 -0
  18. data/LICENSE +202 -0
  19. data/README.md +162 -0
  20. data/Rakefile +47 -0
  21. data/SECURITY.md +42 -0
  22. data/VERSION +1 -1
  23. data/bin/parse-changelog.sh +12 -0
  24. data/ci/configure_v4.sh +12 -0
  25. data/ci/configure_v5.sh +19 -0
  26. data/ci/oauth/keycloak/create_client +18 -0
  27. data/ci/oauth/keycloak/create_user +21 -0
  28. data/ci/oauth/keycloak/fetch_certificate +18 -0
  29. data/ci/oauth/keycloak/keycloak_functions.sh +71 -0
  30. data/ci/oauth/keycloak/standalone.xml +578 -0
  31. data/ci/oauth/keycloak/wait_for_server +56 -0
  32. data/ci/submit-coverage +36 -0
  33. data/conjur-api.gemspec +41 -0
  34. data/dev/Dockerfile.dev +12 -0
  35. data/dev/docker-compose.yml +56 -0
  36. data/dev/start +22 -0
  37. data/dev/stop +5 -0
  38. data/docker-compose.yml +98 -0
  39. data/example/demo_v4.rb +49 -0
  40. data/example/demo_v5.rb +57 -0
  41. data/features/authenticators.feature +41 -0
  42. data/features/authn.feature +14 -0
  43. data/features/authn_local.feature +32 -0
  44. data/features/exists.feature +37 -0
  45. data/features/group.feature +11 -0
  46. data/features/host.feature +50 -0
  47. data/features/host_factory_create_host.feature +28 -0
  48. data/features/host_factory_token.feature +63 -0
  49. data/features/load_policy.feature +61 -0
  50. data/features/members.feature +51 -0
  51. data/features/new_api.feature +36 -0
  52. data/features/permitted.feature +70 -0
  53. data/features/permitted_roles.feature +30 -0
  54. data/features/public_keys.feature +11 -0
  55. data/features/resource_fields.feature +53 -0
  56. data/features/role_fields.feature +15 -0
  57. data/features/rotate_api_key.feature +13 -0
  58. data/features/step_definitions/api_steps.rb +52 -0
  59. data/features/step_definitions/policy_steps.rb +134 -0
  60. data/features/step_definitions/result_steps.rb +11 -0
  61. data/features/support/env.rb +19 -0
  62. data/features/support/hooks.rb +3 -0
  63. data/features/support/world.rb +12 -0
  64. data/features/update_password.feature +14 -0
  65. data/features/user.feature +58 -0
  66. data/features/variable_fields.feature +20 -0
  67. data/features/variable_value.feature +60 -0
  68. data/features_v4/authn_local.feature +27 -0
  69. data/features_v4/exists.feature +29 -0
  70. data/features_v4/host.feature +18 -0
  71. data/features_v4/host_factory_token.feature +49 -0
  72. data/features_v4/members.feature +39 -0
  73. data/features_v4/permitted.feature +15 -0
  74. data/features_v4/permitted_roles.feature +8 -0
  75. data/features_v4/resource_fields.feature +47 -0
  76. data/features_v4/rotate_api_key.feature +13 -0
  77. data/features_v4/step_definitions/api_steps.rb +17 -0
  78. data/features_v4/step_definitions/result_steps.rb +3 -0
  79. data/features_v4/support/env.rb +23 -0
  80. data/features_v4/support/policy.yml +34 -0
  81. data/features_v4/support/world.rb +12 -0
  82. data/features_v4/variable_fields.feature +11 -0
  83. data/features_v4/variable_value.feature +54 -0
  84. data/lib/conjur/acts_as_resource.rb +123 -0
  85. data/lib/conjur/acts_as_role.rb +142 -0
  86. data/lib/conjur/acts_as_rolsource.rb +32 -0
  87. data/lib/conjur/acts_as_user.rb +68 -0
  88. data/lib/conjur/api/authenticators.rb +43 -0
  89. data/lib/conjur/api/authn.rb +144 -0
  90. data/lib/conjur/api/host_factories.rb +71 -0
  91. data/lib/conjur/api/ldap_sync.rb +38 -0
  92. data/lib/conjur/api/policies.rb +56 -0
  93. data/lib/conjur/api/pubkeys.rb +53 -0
  94. data/lib/conjur/api/resources.rb +109 -0
  95. data/lib/conjur/api/roles.rb +98 -0
  96. data/lib/conjur/api/router/v4.rb +206 -0
  97. data/lib/conjur/api/router/v5.rb +269 -0
  98. data/lib/conjur/api/variables.rb +59 -0
  99. data/lib/conjur/api.rb +105 -0
  100. data/lib/conjur/base.rb +355 -0
  101. data/lib/conjur/base_object.rb +57 -0
  102. data/lib/conjur/build_object.rb +47 -0
  103. data/lib/conjur/cache.rb +26 -0
  104. data/lib/conjur/cert_utils.rb +63 -0
  105. data/lib/conjur/cidr.rb +71 -0
  106. data/lib/conjur/configuration.rb +460 -0
  107. data/lib/conjur/escape.rb +129 -0
  108. data/lib/conjur/exceptions.rb +4 -0
  109. data/lib/conjur/group.rb +41 -0
  110. data/lib/conjur/has_attributes.rb +98 -0
  111. data/lib/conjur/host.rb +27 -0
  112. data/lib/conjur/host_factory.rb +75 -0
  113. data/lib/conjur/host_factory_token.rb +78 -0
  114. data/lib/conjur/id.rb +71 -0
  115. data/lib/conjur/layer.rb +9 -0
  116. data/lib/conjur/log.rb +72 -0
  117. data/lib/conjur/log_source.rb +60 -0
  118. data/lib/conjur/policy.rb +34 -0
  119. data/lib/conjur/policy_load_result.rb +61 -0
  120. data/lib/conjur/query_string.rb +12 -0
  121. data/lib/conjur/resource.rb +29 -0
  122. data/lib/conjur/role.rb +29 -0
  123. data/lib/conjur/role_grant.rb +85 -0
  124. data/lib/conjur/routing.rb +29 -0
  125. data/lib/conjur/user.rb +40 -0
  126. data/lib/conjur/variable.rb +208 -0
  127. data/lib/conjur/webservice.rb +30 -0
  128. data/lib/conjur-api/version.rb +24 -0
  129. data/lib/conjur-api.rb +2 -0
  130. data/publish.sh +5 -0
  131. data/spec/api/host_factories_spec.rb +34 -0
  132. data/spec/api_spec.rb +254 -0
  133. data/spec/base_object_spec.rb +13 -0
  134. data/spec/cert_utils_spec.rb +173 -0
  135. data/spec/cidr_spec.rb +34 -0
  136. data/spec/configuration_spec.rb +330 -0
  137. data/spec/has_attributes_spec.rb +63 -0
  138. data/spec/helpers/errors_matcher.rb +34 -0
  139. data/spec/helpers/request_helpers.rb +10 -0
  140. data/spec/id_spec.rb +29 -0
  141. data/spec/ldap_sync_spec.rb +21 -0
  142. data/spec/log_source_spec.rb +13 -0
  143. data/spec/log_spec.rb +42 -0
  144. data/spec/roles_spec.rb +24 -0
  145. data/spec/spec_helper.rb +113 -0
  146. data/spec/ssl_spec.rb +109 -0
  147. data/spec/uri_escape_spec.rb +21 -0
  148. data/test.sh +76 -0
  149. data/tmp/.keep +0 -0
  150. metadata +194 -3
@@ -0,0 +1,61 @@
1
+ Feature: Load a policy.
2
+
3
+ Scenario: Policy can be loaded into a policy id.
4
+ Then I can run the code:
5
+ """
6
+ policy = <<-POLICY
7
+ - !group security_admin
8
+
9
+ - !policy
10
+ id: myapp
11
+ body:
12
+ - !layer
13
+
14
+ - !host-factory
15
+ layers: [ !layer ]
16
+
17
+ - !host app-01
18
+
19
+ - !grant
20
+ role: !layer myapp
21
+ member: !host app-01
22
+ POLICY
23
+
24
+ $conjur.load_policy 'root', policy
25
+ """
26
+
27
+ Scenario: The policy load reports the API keys of created roles.
28
+ Then I can run the code:
29
+ """
30
+ $conjur.load_policy 'root', <<-POLICY
31
+ - !host app-#{random_hex}
32
+ POLICY
33
+ """
34
+ Then the JSON should have "version"
35
+ And the JSON should have "created_roles"
36
+ And the JSON at "created_roles" should have 1 item
37
+
38
+ Scenario: Policy contents can be replaced using POLICY_METHOD_PUT.
39
+ Given I run the code:
40
+ """
41
+ $conjur.load_policy 'root', <<-POLICY
42
+ - !group developers
43
+ - !group operations
44
+ POLICY
45
+ """
46
+ And I run the code:
47
+ """
48
+ $conjur.load_policy 'root', <<-POLICY, method: Conjur::API::POLICY_METHOD_PUT
49
+ --- []
50
+ POLICY
51
+ """
52
+ And I run the code:
53
+ """
54
+ $conjur.resources.map(&:id)
55
+ """
56
+ Then the JSON should be:
57
+ """
58
+ [
59
+ "cucumber:policy:root"
60
+ ]
61
+ """
@@ -0,0 +1,51 @@
1
+ Feature: Display role members and memberships.
2
+
3
+ Background:
4
+ Given I run the code:
5
+ """
6
+ $conjur.load_policy 'root', <<-POLICY
7
+ - !group everyone
8
+ - !group developers
9
+ - !grant
10
+ role: !group everyone
11
+ member: !group developers
12
+ POLICY
13
+ """
14
+
15
+ Scenario: Show a role's members.
16
+ When I run the code:
17
+ """
18
+ $conjur.role('cucumber:group:everyone').members.map(&:as_json)
19
+ """
20
+ Then the JSON should be:
21
+ """
22
+ [
23
+ {
24
+ "admin_option": false,
25
+ "member": "cucumber:group:developers",
26
+ "role": "cucumber:group:everyone"
27
+ },
28
+ {
29
+ "admin_option": true,
30
+ "member": "cucumber:user:admin",
31
+ "role": "cucumber:group:everyone"
32
+ }
33
+ ]
34
+ """
35
+
36
+ Scenario: Show a role's memberships.
37
+ When I run the code:
38
+ """
39
+ $conjur.role('cucumber:group:developers').memberships.map(&:as_json)
40
+ """
41
+ Then the JSON should be:
42
+ """
43
+ [
44
+ {
45
+ "id": "cucumber:group:developers"
46
+ },
47
+ {
48
+ "id": "cucumber:group:everyone"
49
+ }
50
+ ]
51
+ """
@@ -0,0 +1,36 @@
1
+ Feature: Constructing a new API object.
2
+ Background:
3
+ Given a new host
4
+
5
+ Scenario: From API key.
6
+ Then I run the code:
7
+ """
8
+ api = Conjur::API.new_from_key "host/#{@host_id}", @host_api_key
9
+ expect(api.token).to be_instance_of(Hash)
10
+ expect($conjur.resource("cucumber:host:#{@host_id}")).to exist
11
+ """
12
+
13
+ Scenario: From access token.
14
+ Given I run the code:
15
+ """
16
+ @token = Conjur::API.new_from_key("host/#{@host_id}", @host_api_key).token
17
+ """
18
+ Then I run the code:
19
+ """
20
+ api = Conjur::API.new_from_token @token
21
+ expect($conjur.resource("cucumber:host:#{@host_id}")).to exist
22
+ """
23
+
24
+ Scenario: From access token file.
25
+ Given I run the code:
26
+ """
27
+ token = Conjur::API.new_from_key("host/#{@host_id}", @host_api_key).token
28
+ @temp_file = Tempfile.new("token.json")
29
+ @temp_file.write(token.to_json)
30
+ @temp_file.flush
31
+ """
32
+ Then I run the code:
33
+ """
34
+ api = Conjur::API.new_from_token_file @temp_file.path
35
+ expect($conjur.resource("cucumber:host:#{@host_id}")).to exist
36
+ """
@@ -0,0 +1,70 @@
1
+ Feature: Check if a role has permission on a resource.
2
+
3
+ Background:
4
+ Given I run the code:
5
+ """
6
+ @host_id = "app-#{random_hex}"
7
+ @test_user = "user$#{random_hex}"
8
+ @test_host = "host?#{random_hex}"
9
+ response = $conjur.load_policy 'root', <<-POLICY
10
+ - !variable db-password
11
+
12
+ - !layer myapp
13
+
14
+ - !host #{@host_id}
15
+
16
+ - !permit
17
+ role: !layer myapp
18
+ privilege: execute
19
+ resource: !variable db-password
20
+
21
+ - !policy
22
+ id: test
23
+ body:
24
+ - !user #{@test_user}
25
+ - !host #{@test_host}
26
+
27
+ - !permit
28
+ role: !user #{@test_user}@test
29
+ privilege: execute
30
+ resource: !variable db-password
31
+ POLICY
32
+ @host_api_key = response.created_roles["cucumber:host:#{@host_id}"]['api_key']
33
+ expect(@host_api_key).to be
34
+ """
35
+
36
+ Scenario: Check if the current user has the privilege.
37
+ When I run the code:
38
+ """
39
+ $conjur.resource('cucumber:variable:db-password').permitted? 'execute'
40
+ """
41
+ Then the result should be "true"
42
+
43
+ Scenario: Check if a different user has the privilege.
44
+ When I run the code:
45
+ """
46
+ $conjur.resource('cucumber:variable:db-password').permitted? 'execute', role: "cucumber:host:#{@host_id}"
47
+ """
48
+ Then the result should be "false"
49
+
50
+ Scenario: Check if a different user from subpolicy has the privilege.
51
+ When I run the code:
52
+ """
53
+ $conjur.resource('cucumber:variable:db-password').permitted? 'execute', role: "cucumber:user:#{@test_user}@test"
54
+ """
55
+ Then the result should be "true"
56
+
57
+ Scenario: Check if a different host from subpolicy has the privilege.
58
+ When I run the code:
59
+ """
60
+ $conjur.resource('cucumber:variable:db-password').permitted? 'execute', role: "cucumber:host:test/#{@test_host}"
61
+ """
62
+ Then the result should be "false"
63
+
64
+ Scenario: Check if a different user has the privilege, while logged in as that user.
65
+ When I run the code:
66
+ """
67
+ host_api = Conjur::API.new_from_key "host/#{@host_id}", @host_api_key
68
+ host_api.resource('cucumber:variable:db-password').permitted? 'execute'
69
+ """
70
+ Then the result should be "false"
@@ -0,0 +1,30 @@
1
+ Feature: Enumerate roles which have a permission on a resource.
2
+
3
+ Background:
4
+ Given I run the code:
5
+ """
6
+ $conjur.load_policy 'root', <<-POLICY
7
+ - !variable db-password
8
+
9
+ - !layer myapp
10
+
11
+ - !permit
12
+ role: !layer myapp
13
+ privilege: execute
14
+ resource: !variable db-password
15
+ POLICY
16
+ """
17
+
18
+ @wip
19
+ Scenario: Permitted roles can be enumerated.
20
+ When I run the code:
21
+ """
22
+ $conjur.resource('cucumber:variable:db-password').permitted_roles 'execute'
23
+ """
24
+ Then the JSON should be:
25
+ """
26
+ [
27
+ "cucumber:layer:myapp",
28
+ "cucumber:user:admin"
29
+ ]
30
+ """
@@ -0,0 +1,11 @@
1
+ Feature: Fetch public keys for a user.
2
+
3
+ Background:
4
+ Given a new user
5
+
6
+ Scenario: User has a uidnumber.
7
+ When I run the code:
8
+ """
9
+ Conjur::API.public_keys @user.login
10
+ """
11
+ Then the result should be the public key
@@ -0,0 +1,53 @@
1
+ Feature: Display basic resource fields.
2
+
3
+ Background:
4
+ Given I run the code:
5
+ """
6
+ $conjur.load_policy 'root', <<-POLICY
7
+ - !group
8
+ id: developers
9
+ annotations:
10
+ gidnumber: 2000
11
+ POLICY
12
+ """
13
+
14
+ Scenario: Resource exposes id, kind, identifier, and attributes.
15
+ When I run the code:
16
+ """
17
+ resource = $conjur.resource('cucumber:group:developers')
18
+ [ resource.id, resource.account, resource.kind, resource.identifier, resource.attributes ]
19
+ """
20
+ Then the JSON should be:
21
+ """
22
+ [
23
+ "cucumber:group:developers",
24
+ "cucumber",
25
+ "group",
26
+ "developers",
27
+ {
28
+ "annotations": [
29
+ {
30
+ "name": "gidnumber",
31
+ "policy": "cucumber:policy:root",
32
+ "value": "2000"
33
+ }
34
+ ],
35
+ "owner": "cucumber:user:admin",
36
+ "permissions": [
37
+ ],
38
+ "policy": "cucumber:policy:root"
39
+ }
40
+ ]
41
+ """
42
+
43
+ Scenario: Resource#owner is the owner object
44
+ When I run the code:
45
+ """
46
+ $conjur.resource('cucumber:group:developers').owner.id
47
+ """
48
+ Then the result should be "cucumber:user:admin"
49
+ And I run the code:
50
+ """
51
+ $conjur.resource('cucumber:group:developers').class
52
+ """
53
+ Then the result should be "Conjur::Group"
@@ -0,0 +1,15 @@
1
+ Feature: Display basic role fields.
2
+
3
+ Scenario: Login of a user is the login name.
4
+ When I run the code:
5
+ """
6
+ $conjur.role('cucumber:user:alice').login
7
+ """
8
+ Then the result should be "alice"
9
+
10
+ Scenario: Login of a non-user is prefixed with the role kind.
11
+ When I run the code:
12
+ """
13
+ $conjur.role('cucumber:host:myapp').login
14
+ """
15
+ Then the result should be "host/myapp"
@@ -0,0 +1,13 @@
1
+ Feature: Rotate the API key.
2
+
3
+ Scenario: Logged-in user can rotate the API key.
4
+ When I run the code:
5
+ """
6
+ Conjur::API.rotate_api_key 'admin', $api_key
7
+ """
8
+ Then I can run the code:
9
+ """
10
+ $api_key = @result.strip
11
+ $conjur = Conjur::API.new_from_key $username, @result
12
+ $conjur.token
13
+ """
@@ -0,0 +1,52 @@
1
+ Then(/^I(?: can)? run the code:$/) do |code|
2
+ @result = eval(code).tap do |result|
3
+ puts result if ENV['DEBUG']
4
+ end
5
+ end
6
+
7
+ Then(/^this code should fail with "([^"]*)"$/) do |error_msg, code|
8
+ begin
9
+ @result = eval(code)
10
+ rescue Exception => exc
11
+ if not exc.message =~ %r{#{error_msg}}
12
+ fail "'#{error_msg}' was not found in '#{exc.message}'"
13
+ end
14
+ else
15
+ puts @result if ENV['DEBUG']
16
+ fail "The provided block did not raise an error"
17
+ end
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
@@ -0,0 +1,134 @@
1
+ Given(/^a new user$/) do
2
+ @user_id = "user-#{random_hex}"
3
+ @public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDd/PAcCL9rW/zAS7DRns/KYiAvRAEKxBu/0IF32z7x6YiMFcA2hmH4DMYaIY45Xlj7L9uTZamUlRZNjSS9Xm6Lhh7XGceIX2067/MDnH+or9xh5LZs6gb3x7QVtNz26Au5h5kP0xoJ+wpVxvY707BeSax/WQZI8akqd0fD1IqOoafWkcX0ucu5iIgDh08R7zq3vrDHEK7+SoYo9ncHfmOUJ5lmImGiU/WMqM0OzN3RsgxJi/aaHjW1IASTY8TmAtTtjEsxbQXxRVUCAP9vWUZg7p3aqIB6sEP8skgncCUtHBQxUtE1XN8Q8NeFOzau6+9sQTXlPl8c/L4Jc4K96C75 #{@user_id}@example.com"
4
+ response = $conjur.load_policy 'root', <<-POLICY
5
+ - !user
6
+ id: #{@user_id}
7
+ uidnumber: 1000
8
+ public_keys:
9
+ - #{@public_key}
10
+ POLICY
11
+ @user = $conjur.resource("cucumber:user:#{@user_id}")
12
+ @user_api_key = response.created_roles["cucumber:user:#{@user_id}"]['api_key']
13
+ expect(@user_api_key).to be
14
+ end
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
+
25
+ Given(/^a new delegated user$/) do
26
+ # Create a new host that is owned by that user
27
+ step 'a new user'
28
+ @user_owner = @user
29
+ @user_owner_id = @user_id
30
+ @user_owner_api_key = @user_api_key
31
+
32
+ # Create a new user that is owned by the user created earlier
33
+ @user_id = "user-#{random_hex}"
34
+ response = $conjur.load_policy 'root', <<-POLICY
35
+ - !user
36
+ id: #{@user_id}
37
+ owner: !user #{@user_owner_id}
38
+ POLICY
39
+ @user = $conjur.resource("cucumber:user:#{@user_id}")
40
+ @user_api_key = response.created_roles["cucumber:user:#{@user_id}"]['api_key']
41
+ expect(@user_api_key).to be
42
+ end
43
+
44
+ Given(/^a new group$/) do
45
+ @group_id = "group-#{random_hex}"
46
+ response = $conjur.load_policy 'root', <<-POLICY
47
+ - !group
48
+ id: #{@group_id}
49
+ gidnumber: 1000
50
+ POLICY
51
+ @group = $conjur.resource("cucumber:group:#{@group_id}")
52
+ end
53
+
54
+ Given(/^a new host$/) do
55
+ @host_id = "app-#{random_hex}"
56
+ response = $conjur.load_policy 'root', <<-POLICY
57
+ - !host #{@host_id}
58
+ POLICY
59
+ @host_api_key = response.created_roles["cucumber:host:#{@host_id}"]['api_key']
60
+ expect(@host_api_key).to be
61
+ @host = $conjur.resource("cucumber:host:#{@host_id}")
62
+ @host.attributes['api_key'] = @host_api_key
63
+ end
64
+
65
+ Given(/^a new delegated host$/) do
66
+ # Create an owner user
67
+ step 'a new user'
68
+ @host_owner = @user
69
+ @host_owner_id = @user_id
70
+ @host_owner_api_key = @user_api_key
71
+
72
+ # Create a new host that is owned by that user
73
+ @host_id = "app-#{random_hex}"
74
+ response = $conjur.load_policy 'root', <<-POLICY
75
+ - !host
76
+ id: #{@host_id}
77
+ owner: !user #{@host_owner_id}
78
+ POLICY
79
+
80
+ @host_api_key = response.created_roles["cucumber:host:#{@host_id}"]['api_key']
81
+ expect(@host_api_key).to be
82
+ @host = $conjur.resource("cucumber:host:#{@host_id}")
83
+ @host.attributes['api_key'] = @host_api_key
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
@@ -0,0 +1,11 @@
1
+ Then(/^the result should be "([^"]+)"$/) do |expected|
2
+ expect(@result.to_s).to eq(expected.to_s)
3
+ end
4
+
5
+ Then(/^the result should be the public key$/) do
6
+ expect(@result).to eq(@public_key + "\n")
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
@@ -0,0 +1,19 @@
1
+ require 'simplecov'
2
+ require 'nokogiri'
3
+
4
+ SimpleCov.start do
5
+ command_name "#{ENV['RUBY_VERSION']}"
6
+ end
7
+
8
+ require 'json_spec/cucumber'
9
+ require 'conjur/api'
10
+
11
+ Conjur.configuration.appliance_url = ENV['CONJUR_APPLIANCE_URL'] || 'http://localhost/api/v6'
12
+ Conjur.configuration.account = ENV['CONJUR_ACCOUNT'] || 'cucumber'
13
+ Conjur.configuration.authn_local_socket = "/run/authn-local-5/.socket"
14
+
15
+ $username = ENV['CONJUR_AUTHN_LOGIN'] || 'admin'
16
+ $password = ENV['CONJUR_AUTHN_API_KEY'] || 'secret'
17
+
18
+ $api_key = Conjur::API.login $username, $password
19
+ $conjur = Conjur::API.new_from_key $username, $api_key
@@ -0,0 +1,3 @@
1
+ Before do
2
+ $conjur.load_policy 'root', "--- []"
3
+ end
@@ -0,0 +1,12 @@
1
+ module ApiWorld
2
+ def last_json
3
+ @result.to_json
4
+ end
5
+
6
+ def random_hex nbytes = 12
7
+ @random ||= Random.new
8
+ @random.bytes(nbytes).unpack('h*').first
9
+ end
10
+ end
11
+
12
+ World ApiWorld
@@ -0,0 +1,14 @@
1
+ Feature: Change a user's password.
2
+ Background:
3
+ Given a new user
4
+
5
+ Scenario: A user can set/change her password using the current API key.
6
+ When I run the code:
7
+ """
8
+ Conjur::API.update_password @user_id, @user_api_key, 'SEcret12!!!!'
9
+ @new_api_key = Conjur::API.login @user_id, 'SEcret12!!!!'
10
+ """
11
+ Then I can run the code:
12
+ """
13
+ Conjur::API.new_from_key(@user_id, @new_api_key).token
14
+ """
@@ -0,0 +1,58 @@
1
+ Feature: User object
2
+
3
+ Background:
4
+
5
+ Scenario: User has a uidnumber
6
+ Given a new user
7
+ Then I can run the code:
8
+ """
9
+ @user.uidnumber
10
+ """
11
+ Then the result should be "1000"
12
+
13
+ Scenario: Logged-in user is the current_role
14
+ Given a new user
15
+ Then I can run the code:
16
+ """
17
+ expect($conjur.current_role(Conjur.configuration.account).id.to_s).to eq("cucumber:user:admin")
18
+ """
19
+
20
+ # Rotation of own API key should be done via `Conjur::API.rotate_api_key()`
21
+ Scenario: User's own API key cannot be rotated with an API key
22
+ Given a new user
23
+ Then this code should fail with "You cannot rotate your own API key via this method"
24
+ """
25
+ user = Conjur::API.new_from_key(@user.login, @user_api_key).resource(@user.id)
26
+ user.rotate_api_key
27
+ """
28
+
29
+ # Rotation of own API key should be done via `Conjur::API.rotate_api_key()`
30
+ Scenario: User's own API key cannot be rotated with a token
31
+ Given a new user
32
+ Then this code should fail with "You cannot rotate your own API key via this method"
33
+ """
34
+ token = Conjur::API.new_from_key(@user.login, @user_api_key).token
35
+
36
+ user = Conjur::API.new_from_token(token).resource(@user.id)
37
+ user.rotate_api_key
38
+ """
39
+
40
+ Scenario: Delegated user's API key can be rotated with an API key
41
+ Given a new delegated user
42
+ Then I can run the code:
43
+ """
44
+ delegated_user_resource = Conjur::API.new_from_key(@user_owner.login, @user_owner_api_key).resource(@user.id)
45
+ api_key = delegated_user_resource.rotate_api_key
46
+ Conjur::API.new_from_key(delegated_user_resource.login, api_key).token
47
+ """
48
+
49
+ Scenario: Delegated user's API key can be rotated with a token
50
+ Given a new delegated user
51
+ Then I can run the code:
52
+ """
53
+ token = Conjur::API.new_from_key(@user_owner.login, @user_owner_api_key).token
54
+
55
+ delegated_user_resource = Conjur::API.new_from_token(token).resource(@user.id)
56
+ api_key = delegated_user_resource.rotate_api_key
57
+ Conjur::API.new_from_key(delegated_user_resource.login, api_key).token
58
+ """
@@ -0,0 +1,20 @@
1
+ Feature: Display Variable fields.
2
+
3
+ Background:
4
+ Given I run the code:
5
+ """
6
+ $conjur.load_policy 'root', <<-POLICY
7
+ - !variable
8
+ id: ssl-certificate
9
+ kind: SSL certificate
10
+ mime_type: application/x-pem-file
11
+ POLICY
12
+ """
13
+ And I run the code:
14
+ """
15
+ $conjur.resource('cucumber:variable:ssl-certificate')
16
+ """
17
+
18
+ Scenario: Display MIME type and kind
19
+ Then the JSON at "mime_type" should be "application/x-pem-file"
20
+ And the JSON at "kind" should be "SSL certificate"