conjur-api 4.31.0 → 5.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.dockerignore +1 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +22 -3
- data/Dockerfile +12 -3
- data/Gemfile +3 -3
- data/Jenkinsfile +69 -0
- data/LICENSE.md +195 -0
- data/README.md +16 -0
- data/Rakefile +34 -18
- data/ci/wait_for_server.sh +10 -0
- data/conjur-api.gemspec +6 -14
- data/dev/docker-compose.yml +23 -0
- data/dev/empty.yml +2 -0
- data/dev/start.sh +15 -0
- data/dev/stop.sh +6 -0
- data/docker-compose.yml +27 -0
- data/features/exists.feature +37 -0
- data/features/group.feature +11 -0
- data/features/host.feature +20 -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 +43 -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 +4 -54
- data/features/step_definitions/policy_steps.rb +35 -0
- data/features/step_definitions/result_steps.rb +7 -0
- data/features/support/env.rb +14 -5
- data/features/support/hooks.rb +3 -0
- data/features/support/world.rb +5 -6
- data/features/update_password.feature +14 -0
- data/features/user.feature +17 -0
- data/features/variable_fields.feature +20 -0
- data/features/variable_value.feature +67 -0
- data/lib/conjur/acts_as_resource.rb +95 -65
- data/lib/conjur/acts_as_role.rb +102 -51
- data/lib/conjur/{audit-api.rb → acts_as_rolsource.rb} +10 -14
- data/lib/conjur/acts_as_user.rb +13 -22
- data/lib/conjur/api/authn.rb +37 -72
- data/lib/conjur/api/host_factories.rb +35 -55
- data/lib/conjur/api/policies.rb +56 -0
- data/lib/conjur/api/pubkeys.rb +36 -160
- data/lib/conjur/api/resources.rb +32 -116
- data/lib/conjur/api/roles.rb +28 -105
- data/lib/conjur/api/variables.rb +22 -91
- data/lib/conjur/api.rb +19 -46
- data/lib/conjur/base.rb +21 -132
- data/lib/conjur/base_object.rb +57 -0
- data/lib/conjur/{authn-api.rb → build_object.rb} +23 -11
- data/lib/conjur/cast.rb +12 -17
- data/lib/conjur/cert_utils.rb +1 -1
- data/lib/conjur/cidr.rb +1 -1
- data/lib/conjur/configuration.rb +13 -91
- data/lib/conjur/escape.rb +1 -2
- data/lib/conjur/group.rb +9 -65
- data/lib/conjur/has_attributes.rb +22 -59
- data/lib/conjur/host.rb +5 -35
- data/lib/conjur/host_factory.rb +40 -40
- data/lib/conjur/host_factory_token.rb +38 -23
- data/lib/conjur/id.rb +63 -0
- data/lib/conjur/layer.rb +5 -80
- data/lib/conjur/log.rb +1 -1
- data/lib/conjur/log_source.rb +1 -1
- data/lib/conjur/{secret.rb → policy.rb} +11 -14
- data/lib/conjur/{api/secrets.rb → policy_load_result.rb} +35 -22
- data/lib/conjur/query_string.rb +2 -1
- data/lib/conjur/resource.rb +5 -299
- data/lib/conjur/role.rb +5 -317
- data/lib/conjur/role_grant.rb +20 -28
- data/lib/conjur/user.rb +5 -63
- data/lib/conjur/variable.rb +31 -76
- data/lib/conjur/{authz-api.rb → webservice.rb} +8 -16
- data/lib/conjur-api/version.rb +2 -2
- data/publish.sh +7 -0
- data/spec/api_spec.rb +208 -0
- data/spec/cast_spec.rb +21 -0
- data/spec/{lib/cert_utils_spec.rb → cert_utils_spec.rb} +0 -0
- data/spec/{lib/cidr_spec.rb → cidr_spec.rb} +0 -0
- data/spec/{lib/configuration_spec.rb → configuration_spec.rb} +40 -140
- data/spec/{lib/has_attributes_spec.rb → has_attributes_spec.rb} +6 -2
- data/spec/{lib/log_source_spec.rb → log_source_spec.rb} +0 -0
- data/spec/{lib/log_spec.rb → log_spec.rb} +0 -0
- data/spec/roles_spec.rb +24 -0
- data/spec/spec_helper.rb +63 -78
- data/spec/ssl_spec.rb +3 -5
- data/spec/vendor/rest_client_spec.rb +0 -54
- data/test.sh +40 -0
- metadata +122 -281
- data/.kateproject +0 -5
- data/LICENSE +0 -22
- data/ci/test.sh +0 -9
- data/features/audit_resources.feature +0 -15
- data/features/audit_roles.feature +0 -15
- data/features/bootstrap.feature +0 -31
- data/features/step_definitions/cli_steps.rb +0 -5
- data/jenkins.sh +0 -27
- data/lib/conjur/acts_as_asset.rb +0 -88
- data/lib/conjur/annotations.rb +0 -186
- data/lib/conjur/api/audit.rb +0 -138
- data/lib/conjur/api/deputies.rb +0 -57
- data/lib/conjur/api/groups.rb +0 -111
- data/lib/conjur/api/hosts.rb +0 -109
- data/lib/conjur/api/info.rb +0 -126
- data/lib/conjur/api/layers.rb +0 -62
- data/lib/conjur/api/ldapsync.rb +0 -115
- data/lib/conjur/api/users.rb +0 -106
- data/lib/conjur/bootstrap.rb +0 -161
- data/lib/conjur/build_from_response.rb +0 -49
- data/lib/conjur/core-api.rb +0 -74
- data/lib/conjur/deputy.rb +0 -55
- data/lib/conjur/env.rb +0 -54
- data/lib/conjur/event_source.rb +0 -101
- data/lib/conjur/exists.rb +0 -60
- data/lib/conjur/graph.rb +0 -295
- data/lib/conjur/has_id.rb +0 -43
- data/lib/conjur/has_identifier.rb +0 -36
- data/lib/conjur/has_owner.rb +0 -51
- data/lib/conjur/host-factory-api.rb +0 -38
- data/lib/conjur/layer-api.rb +0 -13
- data/lib/conjur/ldap_sync_job.rb +0 -89
- data/lib/conjur/path_based.rb +0 -86
- data/lib/conjur/pubkeys-api.rb +0 -50
- data/lib/conjur/standard_methods.rb +0 -91
- data/reqspeed.rb +0 -20
- data/spec/api/authn_spec.rb +0 -81
- data/spec/api/graph_spec.rb +0 -117
- data/spec/api/groups_spec.rb +0 -40
- data/spec/api/hosts_spec.rb +0 -36
- data/spec/api/info_spec.rb +0 -89
- data/spec/api/layer_spec.rb +0 -18
- data/spec/api/ldapsync_spec.rb +0 -44
- data/spec/api/pubkeys_spec.rb +0 -66
- data/spec/api/resources_spec.rb +0 -92
- data/spec/api/roles_spec.rb +0 -100
- data/spec/api/secrets_spec.rb +0 -16
- data/spec/api/users_spec.rb +0 -71
- data/spec/api/variables_spec.rb +0 -112
- data/spec/cas_rest_client.rb +0 -17
- data/spec/cidr_helper.rb +0 -24
- data/spec/lib/acts_as_user_spec.rb +0 -27
- data/spec/lib/annotations_spec.rb +0 -109
- data/spec/lib/api_spec.rb +0 -480
- data/spec/lib/asset_spec.rb +0 -80
- data/spec/lib/audit_spec.rb +0 -155
- data/spec/lib/build_from_response_spec.rb +0 -49
- data/spec/lib/deputy_spec.rb +0 -25
- data/spec/lib/exists_spec.rb +0 -24
- data/spec/lib/group_spec.rb +0 -18
- data/spec/lib/host_spec.rb +0 -31
- data/spec/lib/resource_spec.rb +0 -240
- data/spec/lib/role_grant_spec.rb +0 -13
- data/spec/lib/role_spec.rb +0 -231
- data/spec/lib/standard_methods_spec.rb +0 -66
- data/spec/lib/user_spec.rb +0 -77
- data/spec/standard_methods_helper.rb +0 -41
- data/spec/variable_spec.rb +0 -101
- data/spec/vcr_cassettes/Conjur_Resource/_create/with_path-like_identifier.yml +0 -87
- data/spec/vcr_cassettes/Conjur_Resource/_create/with_un-encoded_path-like_identifier.yml +0 -87
- data/spec/vcr_cassettes/Conjur_Resource/_create/with_uuid_identifier.yml +0 -87
@@ -0,0 +1,67 @@
|
|
1
|
+
Feature: Work with Variable values.
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I run the code:
|
5
|
+
"""
|
6
|
+
@variable_id = "password"
|
7
|
+
$conjur.load_policy 'root', <<-POLICY
|
8
|
+
- !variable #{@variable_id}
|
9
|
+
- !variable #{@variable_id}-2
|
10
|
+
POLICY
|
11
|
+
@variable = $conjur.resource("cucumber:variable:#{@variable_id}")
|
12
|
+
@variable_2 = $conjur.resource("cucumber:variable:#{@variable_id}-2")
|
13
|
+
"""
|
14
|
+
|
15
|
+
Scenario: Initially the variable has no values
|
16
|
+
When I run the code:
|
17
|
+
"""
|
18
|
+
@variable.version_count
|
19
|
+
"""
|
20
|
+
Then the result should be "0"
|
21
|
+
|
22
|
+
Scenario: Add a value, retrieve the variable metadata and the value.
|
23
|
+
Given I run the code:
|
24
|
+
"""
|
25
|
+
@variable.add_value 'value-0'
|
26
|
+
"""
|
27
|
+
When I run the code:
|
28
|
+
"""
|
29
|
+
@variable.version_count
|
30
|
+
"""
|
31
|
+
Then the result should be "1"
|
32
|
+
And I run the code:
|
33
|
+
"""
|
34
|
+
@variable.value
|
35
|
+
"""
|
36
|
+
Then the result should be "value-0"
|
37
|
+
|
38
|
+
Scenario: Retrieve a historical value.
|
39
|
+
Given I run the code:
|
40
|
+
"""
|
41
|
+
@variable.add_value 'value-0'
|
42
|
+
@variable.add_value 'value-1'
|
43
|
+
@variable.add_value 'value-2'
|
44
|
+
"""
|
45
|
+
When I run the code:
|
46
|
+
"""
|
47
|
+
@variable.value(1)
|
48
|
+
"""
|
49
|
+
Then the result should be "value-0"
|
50
|
+
|
51
|
+
Scenario: Retrieve multiple values in a batch
|
52
|
+
Given I run the code:
|
53
|
+
"""
|
54
|
+
@variable.add_value 'value-0'
|
55
|
+
@variable_2.add_value 'value-2'
|
56
|
+
"""
|
57
|
+
When I run the code:
|
58
|
+
"""
|
59
|
+
$conjur.variable_values([ @variable, @variable_2 ].map(&:id))
|
60
|
+
"""
|
61
|
+
Then the JSON should be:
|
62
|
+
"""
|
63
|
+
{
|
64
|
+
"cucumber:variable:password": "value-0",
|
65
|
+
"cucumber:variable:password-2": "value-2"
|
66
|
+
}
|
67
|
+
"""
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright
|
2
|
+
# Copyright 2013-2017 Conjur Inc
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
5
5
|
# this software and associated documentation files (the "Software"), to deal in
|
@@ -19,89 +19,119 @@
|
|
19
19
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
20
|
#
|
21
21
|
|
22
|
-
require 'active_support/dependencies/autoload'
|
23
|
-
require 'active_support/core_ext'
|
24
|
-
|
25
22
|
module Conjur
|
26
|
-
|
27
|
-
# This module is included in asset classes that have an associated resource.
|
23
|
+
# This module is included in object classes that have resource behavior.
|
28
24
|
module ActsAsResource
|
29
|
-
#
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
# NOTE: should we use specific class to build sub-url below?
|
35
|
-
Conjur::Resource.new(Conjur::Authz::API.host, self.options)[[ core_conjur_account, 'resources', path_escape(resource_kind), path_escape(resource_id) ].join('/')]
|
25
|
+
# @api private
|
26
|
+
def self.included(base)
|
27
|
+
base.include HasAttributes
|
28
|
+
base.include Escape
|
29
|
+
base.extend QueryString
|
36
30
|
end
|
37
31
|
|
38
|
-
#
|
32
|
+
# The full role id of the role that owns this resource.
|
39
33
|
#
|
40
|
-
# @
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
# The kind of resource underlying the asset. The kind is the second token in
|
46
|
-
# a Conjur id like `"account:kind:id"`.
|
34
|
+
# @example
|
35
|
+
# api.current_role # => 'conjur:user:jon'
|
36
|
+
# resource = api.create_resource 'conjur:example:resource-owner'
|
37
|
+
# resource.owner # => 'conjur:user:jon'
|
47
38
|
#
|
48
|
-
# @
|
49
|
-
|
50
|
-
|
51
|
-
self.class.name.split("::")[-1].underscore.split('/').join('-')
|
39
|
+
# @return [String] the full role id of this resource's owner.
|
40
|
+
def owner
|
41
|
+
build_object attributes['owner'], default_class: Role
|
52
42
|
end
|
53
43
|
|
54
|
-
#
|
44
|
+
# Check whether this object exists by performing a HEAD request to its URL.
|
55
45
|
#
|
56
|
-
#
|
57
|
-
# resource id returned by {#resourceid}.
|
46
|
+
# This method will return false if the object doesn't exist.
|
58
47
|
#
|
59
|
-
# @
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
|
69
|
-
|
70
|
-
|
48
|
+
# @example
|
49
|
+
# does_not_exist = api.user 'does-not-exist' # This returns without error.
|
50
|
+
#
|
51
|
+
# # this is wrong!
|
52
|
+
# owner = does_not_exist.owner # raises RestClient::ResourceNotFound
|
53
|
+
#
|
54
|
+
# # this is right!
|
55
|
+
# owner = if does_not_exist.exists?
|
56
|
+
# does_not_exist.owner
|
57
|
+
# else
|
58
|
+
# nil # or some sensible default
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# @return [Boolean] does it exist?
|
62
|
+
def exists?
|
63
|
+
begin
|
64
|
+
rbac_resource_resource.head
|
65
|
+
true
|
66
|
+
rescue RestClient::Forbidden
|
67
|
+
true
|
68
|
+
rescue RestClient::ResourceNotFound
|
69
|
+
false
|
70
|
+
end
|
71
71
|
end
|
72
72
|
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
73
|
+
# Lists roles that have a specified privilege on the resource.
|
74
|
+
#
|
75
|
+
# This will return only roles of which api.current_user is a member.
|
76
76
|
#
|
77
|
-
#
|
77
|
+
# Options:
|
78
78
|
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
# variable = api.variable 'some-project/development/postgres-uri'
|
82
|
-
# variable.permit 'execute', group
|
79
|
+
# * **offset** Zero-based offset into the result set.
|
80
|
+
# * **limit** Total number of records returned.
|
83
81
|
#
|
84
|
-
# @
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
|
91
|
-
|
82
|
+
# @example
|
83
|
+
# resource = api.resource 'conjur:variable:example'
|
84
|
+
# resource.permitted_roles 'execute' # => ['conjur:user:admin']
|
85
|
+
# # After permitting 'execute' to user 'jon'
|
86
|
+
# resource.permitted_roles 'execute' # => ['conjur:user:admin', 'conjur:user:jon']
|
87
|
+
#
|
88
|
+
# @param privilege [String] the privilege
|
89
|
+
# @return [Array<String>] the ids of roles that have `privilege` on this resource.
|
90
|
+
def permitted_roles privilege
|
91
|
+
options = {}
|
92
|
+
options[:permitted_roles] = true
|
93
|
+
options[:privilege] = privilege
|
94
|
+
result = JSON.parse rbac_resource_resource[options_querystring options].get
|
95
|
+
if result.is_a?(Hash) && ( count = result['count'] )
|
96
|
+
count
|
97
|
+
else
|
98
|
+
result
|
99
|
+
end
|
92
100
|
end
|
93
101
|
|
94
|
-
|
95
|
-
#
|
102
|
+
# True if the logged-in role, or a role specified using the :role option, has the
|
103
|
+
# specified +privilege+ on this resource.
|
96
104
|
#
|
97
|
-
# @
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
105
|
+
# @example
|
106
|
+
# api.current_role # => 'conjur:cat:mouse'
|
107
|
+
# resource.permitted_roles 'execute' # => ['conjur:user:admin', 'conjur:cat:mouse']
|
108
|
+
# resource.permitted_roles 'update', # => ['conjur:user:admin', 'conjur:cat:gino']
|
101
109
|
#
|
102
|
-
#
|
103
|
-
|
104
|
-
|
110
|
+
# resource.permitted? 'update' # => false, `mouse` can't update this resource
|
111
|
+
# resource.permitted? 'execute' # => true, `mouse` can execute it.
|
112
|
+
# resource.permitted? 'update', role: 'conjur:cat:gino' # => true, `gino` can update it.
|
113
|
+
# @param privilege [String] the privilege to check
|
114
|
+
# @param role [String,nil] :role check whether the role given by this full role id is permitted
|
115
|
+
# instead of checking +api.current_role+.
|
116
|
+
# @return [Boolean]
|
117
|
+
def permitted? privilege, role: nil
|
118
|
+
options = {}
|
119
|
+
options[:check] = true
|
120
|
+
options[:privilege] = privilege
|
121
|
+
options[:role] = cast_to_id(role) if role
|
122
|
+
rbac_resource_resource[options_querystring options].get
|
123
|
+
true
|
124
|
+
rescue RestClient::Forbidden
|
125
|
+
false
|
126
|
+
rescue RestClient::ResourceNotFound
|
127
|
+
false
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
# RestClient::Resource for RBAC resource operations.
|
133
|
+
def rbac_resource_resource
|
134
|
+
RestClient::Resource.new(Conjur.configuration.core_url, credentials)['resources'][id.to_url_path]
|
105
135
|
end
|
106
136
|
end
|
107
137
|
end
|
data/lib/conjur/acts_as_role.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright
|
2
|
+
# Copyright 2013-2017 Conjur Inc
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
5
5
|
# this software and associated documentation files (the "Software"), to deal in
|
@@ -29,69 +29,120 @@ module Conjur
|
|
29
29
|
# The {Conjur::ActsAsRole} module itself should be considered private, but it's methods are
|
30
30
|
# public when added to a Conjur asset class.
|
31
31
|
module ActsAsRole
|
32
|
-
|
33
|
-
#
|
34
|
-
#
|
35
|
-
|
36
|
-
|
37
|
-
# @return [String] the qualified role id
|
38
|
-
def roleid
|
39
|
-
[ core_conjur_account, role_kind, id ].join(':')
|
32
|
+
|
33
|
+
# Login name of the role. This is formed from the role kind and role id.
|
34
|
+
# For users, the role kind can be omitted.
|
35
|
+
def login
|
36
|
+
[ kind, identifier ].delete_if{|t| t == "user"}.join('/')
|
40
37
|
end
|
41
|
-
alias role_id roleid
|
42
38
|
|
43
|
-
#
|
44
|
-
# Conjur assets, for example, `'user'`, `'group'`, or `'variable'`.
|
39
|
+
# Check whether this object exists by performing a HEAD request to its URL.
|
45
40
|
#
|
46
|
-
#
|
41
|
+
# This method will return false if the object doesn't exist.
|
47
42
|
#
|
48
|
-
# @
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
#
|
54
|
-
|
55
|
-
|
56
|
-
|
43
|
+
# @example
|
44
|
+
# does_not_exist = api.user 'does-not-exist' # This returns without error.
|
45
|
+
#
|
46
|
+
# # this is wrong!
|
47
|
+
# owner = does_not_exist.members # raises RestClient::ResourceNotFound
|
48
|
+
#
|
49
|
+
# # this is right!
|
50
|
+
# owner = if does_not_exist.exists?
|
51
|
+
# does_not_exist.members
|
52
|
+
# else
|
53
|
+
# nil # or some sensible default
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# @return [Boolean] does it exist?
|
57
|
+
def exists?
|
58
|
+
begin
|
59
|
+
rbac_role_resource.head
|
60
|
+
true
|
61
|
+
rescue RestClient::Forbidden
|
62
|
+
true
|
63
|
+
rescue RestClient::ResourceNotFound
|
64
|
+
false
|
65
|
+
end
|
57
66
|
end
|
58
67
|
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
# This method is primarily intended for use in the
|
63
|
-
# {http://developer.conjur.net/reference/tools/utilities/policy-load.html Conjur Policy DSL},
|
64
|
-
# and simply delegates to {Conjur::Resource#permit}. For code clarity, you might consider using
|
65
|
-
# that method instead.
|
68
|
+
# Find all roles of which this role is a member. By default, role relationships are recursively expanded,
|
69
|
+
# so if `a` is a member of `b`, and `b` is a member of `c`, `a.all` will include `c`.
|
66
70
|
#
|
67
71
|
# ### Permissions
|
72
|
+
# You must be a member of the role to call this method.
|
68
73
|
#
|
69
|
-
#
|
74
|
+
# You can restrict the roles returned to one or more role ids. This feature is mainly useful
|
75
|
+
# for checking whether this role is a member of any of a set of roles.
|
70
76
|
#
|
71
|
-
#
|
72
|
-
# @param [String] privilege the privilege to allow this role to perform, e.g. `'execute'` or `'update'`
|
73
|
-
# @param [Conjur::Resource, #resource_id, String] resource the resource to grant `privilege` on.
|
74
|
-
# @param [Hash] options Options to pass through to RestClient::Resource#post
|
75
|
-
# @option options [Boolean] :grant_option whether this role will be able to grant the privilege to other roles.
|
76
|
-
# @return [void]
|
77
|
-
def can(privilege, resource, options = {})
|
78
|
-
require 'conjur/resource'
|
79
|
-
Conjur::Resource.new(Conjur::Authz::API.host, self.options)[Conjur::API.parse_resource_id(resource).join('/')].permit privilege, self.roleid, options
|
80
|
-
end
|
81
|
-
|
82
|
-
# Deny the asset's role the ability to perform `privilege` on `resource`. This operation is the inverse of {#can}.
|
77
|
+
# ### Options
|
83
78
|
#
|
84
|
-
#
|
85
|
-
# {http://developer.conjur.net/reference/tools/utilities/policy-load.html Conjur Policy DSL},
|
86
|
-
# and simply delegates to {Conjur::Resource#permit}. For code clarity, you might consider using
|
87
|
-
# that method instead.
|
79
|
+
# * **recursive** Defaults to +true+, performs recursive expansion of the memberships.
|
88
80
|
#
|
89
|
-
# @
|
81
|
+
# @example Show all roles of which `"conjur:group:pubkeys-1.0/key-managers"` is a member
|
82
|
+
# # Add alice to the group, so we see something interesting
|
83
|
+
# key_managers = api.group('pubkeys-1.0/key-managers')
|
84
|
+
# key_managers.add_member api.user('alice')
|
90
85
|
#
|
91
|
-
#
|
92
|
-
|
93
|
-
|
94
|
-
|
86
|
+
# # Show the memberships, mapped to the member ids.
|
87
|
+
# key_managers.role.all.map(&:id)
|
88
|
+
# # => ["conjur:group:pubkeys-1.0/admin", "conjur:user:alice"]
|
89
|
+
#
|
90
|
+
# @example See if role `"conjur:user:alice"` is a member of either `"conjur:groups:developers"` or `"conjur:group:ops"`
|
91
|
+
# is_member = api.role('conjur:user:alice').all(filter: ['conjur:group:developers', 'conjur:group:ops']).any?
|
92
|
+
#
|
93
|
+
# @param [Hash] options options for the request
|
94
|
+
# @return [Array<Conjur::Role>] Roles of which this role is a member
|
95
|
+
def memberships options = {}
|
96
|
+
request = if options.delete(:recursive) == false
|
97
|
+
options["memberships"] = true
|
98
|
+
else
|
99
|
+
options["all"] = true
|
100
|
+
end
|
101
|
+
if filter = options.delete(:filter)
|
102
|
+
filter = [filter] unless filter.is_a?(Array)
|
103
|
+
options["filter"] = filter.map{ |obj| cast_to_id(obj) }
|
104
|
+
end
|
105
|
+
|
106
|
+
result = JSON.parse(rbac_role_resource[options_querystring options].get)
|
107
|
+
if result.is_a?(Hash) && ( count = result['count'] )
|
108
|
+
count
|
109
|
+
else
|
110
|
+
host = Conjur.configuration.core_url
|
111
|
+
result.collect do |item|
|
112
|
+
if item.is_a?(String)
|
113
|
+
build_object(item, default_class: Role)
|
114
|
+
else
|
115
|
+
RoleGrant.parse_from_json(item, self.options)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Fetch the direct members of this role. The results are *not* recursively expanded).
|
122
|
+
#
|
123
|
+
# ### Permissions
|
124
|
+
# You must be a member of the role to call this method.
|
125
|
+
#
|
126
|
+
# @param options [Hash, nil] extra parameters to pass to the webservice method.
|
127
|
+
# @return [Array<Conjur::RoleGrant>] the role memberships
|
128
|
+
# @raise [RestClient::Forbidden] if you don't have permission to perform this operation
|
129
|
+
def members options = {}
|
130
|
+
options["members"] = true
|
131
|
+
result = JSON.parse(rbac_role_resource[options_querystring options].get)
|
132
|
+
if result.is_a?(Hash) && ( count = result['count'] )
|
133
|
+
count
|
134
|
+
else
|
135
|
+
result['members'].collect do |json|
|
136
|
+
RoleGrant.parse_from_json(json, credentials)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
# RestClient::Resource for RBAC role operations.
|
144
|
+
def rbac_role_resource
|
145
|
+
RestClient::Resource.new(Conjur.configuration.core_url, credentials)['roles'][id.to_url_path]
|
95
146
|
end
|
96
147
|
end
|
97
148
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (C) 2013 Conjur Inc
|
2
|
+
# Copyright (C) 2013-2017 Conjur Inc
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
5
5
|
# this software and associated documentation files (the "Software"), to deal in
|
@@ -18,19 +18,15 @@
|
|
18
18
|
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
19
19
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
20
|
#
|
21
|
-
|
22
21
|
module Conjur
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
-
end
|
22
|
+
|
23
|
+
# This module provides methods for things that have an associated {Conjur::Role} and
|
24
|
+
# {Conjur::Resource}.
|
25
|
+
module ActsAsRolsource
|
26
|
+
# @api private
|
27
|
+
def self.included(base)
|
28
|
+
base.include ActsAsRole
|
29
|
+
base.include ActsAsResource
|
33
30
|
end
|
34
31
|
end
|
35
|
-
end
|
36
|
-
require 'conjur/api/audit'
|
32
|
+
end
|
data/lib/conjur/acts_as_user.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright
|
2
|
+
# Copyright 2013-2017 Conjur Inc
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
5
5
|
# this software and associated documentation files (the "Software"), to deal in
|
@@ -22,17 +22,20 @@ module Conjur
|
|
22
22
|
# This module provides methods for things that are like users (specifically, those that have
|
23
23
|
# api keys).
|
24
24
|
module ActsAsUser
|
25
|
-
|
25
|
+
# @api private
|
26
|
+
def self.included(base)
|
27
|
+
base.include ActsAsRolsource
|
28
|
+
end
|
26
29
|
|
27
30
|
# Returns a newly created user's api_key.
|
28
31
|
#
|
29
|
-
# @note
|
30
|
-
#
|
32
|
+
# @note The API key is not returned by {API#resource}. It is only available
|
33
|
+
# via {API#login}, when the object is newly created, and when the API key is rotated.
|
31
34
|
#
|
32
35
|
# @return [String] the api key
|
33
36
|
# @raise [Exception] when the object isn't newly created.
|
34
37
|
def api_key
|
35
|
-
attributes['api_key'] or raise "api_key is only available on a newly created #{
|
38
|
+
attributes['api_key'] or raise "api_key is only available on a newly created #{kind}"
|
36
39
|
end
|
37
40
|
|
38
41
|
# Create an api logged in as this user-like thing.
|
@@ -41,34 +44,22 @@ module Conjur
|
|
41
44
|
# @see #api_key
|
42
45
|
# @return [Conjur::API] an api logged in as this user-like thing.
|
43
46
|
def api
|
44
|
-
Conjur::API.new_from_key login, api_key
|
47
|
+
Conjur::API.new_from_key login, api_key, account: account
|
45
48
|
end
|
46
49
|
|
47
|
-
# Rotate this
|
50
|
+
# Rotate this role's API key. You must have `update` permission on the user to do so.
|
48
51
|
#
|
49
52
|
# @note You will not be able to access the API key returned by this method later, so you should
|
50
53
|
# probably hang onto it it.
|
51
54
|
#
|
52
|
-
# @note You cannot rotate your own API key with this method.
|
55
|
+
# @note You cannot rotate your own API key with this method. To do so, use `Conjur::API.rotate_api_key`
|
53
56
|
#
|
54
57
|
# @note This feature requires a Conjur appliance running version 4.6 or higher.
|
55
58
|
#
|
56
59
|
# @return [String] the new API key for this user.
|
57
60
|
def rotate_api_key
|
58
|
-
path = "
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
# Set login network restrictions for the user.
|
63
|
-
#
|
64
|
-
# @param [Array<String, IPAddr>] networks which allow logging in. Set to empty to remove restrictions
|
65
|
-
def set_cidr_restrictions networks
|
66
|
-
authn_user = RestClient::Resource.new(Conjur::Authn::API.host, options)\
|
67
|
-
["users?id=#{fully_escape login}"]
|
68
|
-
|
69
|
-
# we need use JSON here to be able to PUT an empty array
|
70
|
-
params = { cidr: [*networks].map(&CIDR.method(:validate)).map(&:to_s) }
|
71
|
-
authn_user.put params.to_json, content_type: :json
|
61
|
+
path = "authn/#{path_escape account}/api_key?role=#{id}"
|
62
|
+
core_resource[path].put('').body
|
72
63
|
end
|
73
64
|
end
|
74
65
|
end
|