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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +10 -0
- data/.dockerignore +1 -0
- data/.github/CODEOWNERS +10 -0
- data/.gitignore +32 -0
- data/.gitleaks.toml +219 -0
- data/.overcommit.yml +16 -0
- data/.project +18 -0
- data/.rubocop.yml +3 -0
- data/.rubocop_settings.yml +86 -0
- data/.rubocop_todo.yml +709 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +448 -0
- data/CONTRIBUTING.md +138 -0
- data/Dockerfile +16 -0
- data/Gemfile +7 -0
- data/Jenkinsfile +136 -0
- data/LICENSE +202 -0
- data/README.md +162 -0
- data/Rakefile +47 -0
- data/SECURITY.md +42 -0
- data/VERSION +1 -1
- data/bin/parse-changelog.sh +12 -0
- data/ci/configure_v4.sh +12 -0
- data/ci/configure_v5.sh +19 -0
- data/ci/oauth/keycloak/create_client +18 -0
- data/ci/oauth/keycloak/create_user +21 -0
- data/ci/oauth/keycloak/fetch_certificate +18 -0
- data/ci/oauth/keycloak/keycloak_functions.sh +71 -0
- data/ci/oauth/keycloak/standalone.xml +578 -0
- data/ci/oauth/keycloak/wait_for_server +56 -0
- data/ci/submit-coverage +36 -0
- data/conjur-api.gemspec +41 -0
- data/dev/Dockerfile.dev +12 -0
- data/dev/docker-compose.yml +56 -0
- data/dev/start +22 -0
- data/dev/stop +5 -0
- data/docker-compose.yml +98 -0
- data/example/demo_v4.rb +49 -0
- data/example/demo_v5.rb +57 -0
- data/features/authenticators.feature +41 -0
- data/features/authn.feature +14 -0
- data/features/authn_local.feature +32 -0
- data/features/exists.feature +37 -0
- data/features/group.feature +11 -0
- data/features/host.feature +50 -0
- data/features/host_factory_create_host.feature +28 -0
- data/features/host_factory_token.feature +63 -0
- data/features/load_policy.feature +61 -0
- data/features/members.feature +51 -0
- data/features/new_api.feature +36 -0
- data/features/permitted.feature +70 -0
- data/features/permitted_roles.feature +30 -0
- data/features/public_keys.feature +11 -0
- data/features/resource_fields.feature +53 -0
- data/features/role_fields.feature +15 -0
- data/features/rotate_api_key.feature +13 -0
- data/features/step_definitions/api_steps.rb +52 -0
- data/features/step_definitions/policy_steps.rb +134 -0
- data/features/step_definitions/result_steps.rb +11 -0
- data/features/support/env.rb +19 -0
- data/features/support/hooks.rb +3 -0
- data/features/support/world.rb +12 -0
- data/features/update_password.feature +14 -0
- data/features/user.feature +58 -0
- data/features/variable_fields.feature +20 -0
- data/features/variable_value.feature +60 -0
- data/features_v4/authn_local.feature +27 -0
- data/features_v4/exists.feature +29 -0
- data/features_v4/host.feature +18 -0
- data/features_v4/host_factory_token.feature +49 -0
- data/features_v4/members.feature +39 -0
- data/features_v4/permitted.feature +15 -0
- data/features_v4/permitted_roles.feature +8 -0
- data/features_v4/resource_fields.feature +47 -0
- data/features_v4/rotate_api_key.feature +13 -0
- data/features_v4/step_definitions/api_steps.rb +17 -0
- data/features_v4/step_definitions/result_steps.rb +3 -0
- data/features_v4/support/env.rb +23 -0
- data/features_v4/support/policy.yml +34 -0
- data/features_v4/support/world.rb +12 -0
- data/features_v4/variable_fields.feature +11 -0
- data/features_v4/variable_value.feature +54 -0
- data/lib/conjur/acts_as_resource.rb +123 -0
- data/lib/conjur/acts_as_role.rb +142 -0
- data/lib/conjur/acts_as_rolsource.rb +32 -0
- data/lib/conjur/acts_as_user.rb +68 -0
- data/lib/conjur/api/authenticators.rb +43 -0
- data/lib/conjur/api/authn.rb +144 -0
- data/lib/conjur/api/host_factories.rb +71 -0
- data/lib/conjur/api/ldap_sync.rb +38 -0
- data/lib/conjur/api/policies.rb +56 -0
- data/lib/conjur/api/pubkeys.rb +53 -0
- data/lib/conjur/api/resources.rb +109 -0
- data/lib/conjur/api/roles.rb +98 -0
- data/lib/conjur/api/router/v4.rb +206 -0
- data/lib/conjur/api/router/v5.rb +269 -0
- data/lib/conjur/api/variables.rb +59 -0
- data/lib/conjur/api.rb +105 -0
- data/lib/conjur/base.rb +355 -0
- data/lib/conjur/base_object.rb +57 -0
- data/lib/conjur/build_object.rb +47 -0
- data/lib/conjur/cache.rb +26 -0
- data/lib/conjur/cert_utils.rb +63 -0
- data/lib/conjur/cidr.rb +71 -0
- data/lib/conjur/configuration.rb +460 -0
- data/lib/conjur/escape.rb +129 -0
- data/lib/conjur/exceptions.rb +4 -0
- data/lib/conjur/group.rb +41 -0
- data/lib/conjur/has_attributes.rb +98 -0
- data/lib/conjur/host.rb +27 -0
- data/lib/conjur/host_factory.rb +75 -0
- data/lib/conjur/host_factory_token.rb +78 -0
- data/lib/conjur/id.rb +71 -0
- data/lib/conjur/layer.rb +9 -0
- data/lib/conjur/log.rb +72 -0
- data/lib/conjur/log_source.rb +60 -0
- data/lib/conjur/policy.rb +34 -0
- data/lib/conjur/policy_load_result.rb +61 -0
- data/lib/conjur/query_string.rb +12 -0
- data/lib/conjur/resource.rb +29 -0
- data/lib/conjur/role.rb +29 -0
- data/lib/conjur/role_grant.rb +85 -0
- data/lib/conjur/routing.rb +29 -0
- data/lib/conjur/user.rb +40 -0
- data/lib/conjur/variable.rb +208 -0
- data/lib/conjur/webservice.rb +30 -0
- data/lib/conjur-api/version.rb +24 -0
- data/lib/conjur-api.rb +2 -0
- data/publish.sh +5 -0
- data/spec/api/host_factories_spec.rb +34 -0
- data/spec/api_spec.rb +254 -0
- data/spec/base_object_spec.rb +13 -0
- data/spec/cert_utils_spec.rb +173 -0
- data/spec/cidr_spec.rb +34 -0
- data/spec/configuration_spec.rb +330 -0
- data/spec/has_attributes_spec.rb +63 -0
- data/spec/helpers/errors_matcher.rb +34 -0
- data/spec/helpers/request_helpers.rb +10 -0
- data/spec/id_spec.rb +29 -0
- data/spec/ldap_sync_spec.rb +21 -0
- data/spec/log_source_spec.rb +13 -0
- data/spec/log_spec.rb +42 -0
- data/spec/roles_spec.rb +24 -0
- data/spec/spec_helper.rb +113 -0
- data/spec/ssl_spec.rb +109 -0
- data/spec/uri_escape_spec.rb +21 -0
- data/test.sh +76 -0
- data/tmp/.keep +0 -0
- 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,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,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"
|