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
data/lib/conjur/api/resources.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,44 +22,11 @@ require 'conjur/resource'
|
|
22
22
|
|
23
23
|
module Conjur
|
24
24
|
class API
|
25
|
-
|
26
|
-
|
27
|
-
# Create a {http://developer.conjur.net/reference/services/authorization/resource Conjur Resource}.
|
28
|
-
# Resources are entities on which roles have permissions. A resource might represent a secret, a
|
29
|
-
# web service route, or be part of a higher level construct such as a user or group.
|
30
|
-
#
|
31
|
-
# If `:acting_as` is not present in `options`, you will be the owner of the new role. If it is present,
|
32
|
-
# your role must be a member of the given role (see {Conjur::Role#member_of?}).
|
33
|
-
#
|
34
|
-
# @example Create an abstract resource to represent a web service route
|
35
|
-
# # Notice that we can omit the account in the identifier
|
36
|
-
# service_resource = api.create_resource 'web-service:list-gadgets'
|
37
|
-
# service_resource.resource_id # => 'conjur:web-service:list-gadgets'
|
38
|
-
#
|
39
|
-
# # In a gatekeeper for the web service, we can use the resource to control access
|
40
|
-
# get '/gadgets' do
|
41
|
-
# # We'll assume that we've verified the Conjur authn token in the request, and stored the
|
42
|
-
# # corresponding identifier in `request_role_id`
|
43
|
-
# halt(403) unless api.resource('conjur:web-service:list-gadgets').permitted? 'read', request_role_id
|
44
|
-
# render_json find_gadgets
|
45
|
-
# end
|
46
|
-
#
|
47
|
-
# @example Create a role owned by another role
|
48
|
-
# alice = api.role('user:alice')
|
49
|
-
# api.current_role.member_of? alice # true, the operation will fail if this is false
|
50
|
-
# res = api.create_resource 'example:owned', acting_as: 'user:alice'
|
51
|
-
# res.owner # "conjur:user:alice"
|
52
|
-
#
|
53
|
-
# @param [String] identifier an id of the form `"<account>:<kind>:<id>"` or `"<kind>:<id>"`
|
54
|
-
# @param options [Hash] options for the request
|
55
|
-
# @option options [String, #role_id] :acting_as the role-ish thing or role id that will own the new resource
|
56
|
-
# @return [Conjur::Role] the new role
|
57
|
-
def create_resource(identifier, options = {})
|
58
|
-
resource(identifier).tap do |r|
|
59
|
-
r.create(options)
|
60
|
-
end
|
61
|
-
end
|
25
|
+
include QueryString
|
26
|
+
include BuildObject
|
62
27
|
|
28
|
+
#@!group Resources
|
29
|
+
|
63
30
|
# Find a resource by it's id. The id given to this method must be qualified by a kind, but the account is
|
64
31
|
# optional.
|
65
32
|
#
|
@@ -68,23 +35,10 @@ module Conjur
|
|
68
35
|
# The resource **must** be visible to the current role. This is the case if the current role is the owner of
|
69
36
|
# the resource, or has any privilege on it.
|
70
37
|
#
|
71
|
-
# @
|
72
|
-
# def find_or_create_resource resource_id
|
73
|
-
# resource = api.resource resource_id
|
74
|
-
# unless resource.exists?
|
75
|
-
# resource = api.create_resource resource_id
|
76
|
-
# end
|
77
|
-
# resource
|
78
|
-
# end
|
79
|
-
#
|
80
|
-
# # ...
|
81
|
-
# example_resource = find_or_create_resource 'example:find-or-create'
|
82
|
-
# example_resource.exists? # always true
|
83
|
-
#
|
84
|
-
# @param identifier [String] a qualified resource identifier, optionally including an account
|
38
|
+
# @param id [String] a fully qualified resource identifier
|
85
39
|
# @return [Conjur::Resource] the resource, which may or may not exist
|
86
|
-
def resource
|
87
|
-
|
40
|
+
def resource id
|
41
|
+
build_object id
|
88
42
|
end
|
89
43
|
|
90
44
|
# Find all resources visible to the current role that match the given search criteria.
|
@@ -108,19 +62,12 @@ module Conjur
|
|
108
62
|
# @example Search for resources annotated with the text "WebService Route"
|
109
63
|
# webservice_routes = api.resources search: "WebService Route"
|
110
64
|
#
|
111
|
-
# # Check that it worked:
|
112
|
-
# webservice_routes.each do |resource|
|
113
|
-
# searchable = [resource.annotations.to_h.values, resource.resource_id]
|
114
|
-
# raise "FAILED" unless searchable.flatten.any?{|s| s.include? "WebService Route"}
|
115
|
-
# end
|
116
|
-
#
|
117
65
|
# @example Restrict the search to 'group' resources
|
118
66
|
# groups = api.resources kind: 'group'
|
119
67
|
#
|
120
68
|
# # Correct behavior:
|
121
69
|
# expect(groups.all?{|g| g.kind == 'group'}).to be_true
|
122
70
|
#
|
123
|
-
#
|
124
71
|
# @example Get every single resource in a performant way
|
125
72
|
# resources = []
|
126
73
|
# limit = 25
|
@@ -131,17 +78,32 @@ module Conjur
|
|
131
78
|
# end
|
132
79
|
# # do something with your resources
|
133
80
|
#
|
134
|
-
# @param
|
135
|
-
# @option
|
136
|
-
# @option
|
137
|
-
# @option
|
138
|
-
# @option
|
81
|
+
# @param options [Hash] search criteria
|
82
|
+
# @option options [String] :search find resources whose ids or annotations contain this string
|
83
|
+
# @option options [String] :kind find resources whose `kind` matches this string
|
84
|
+
# @option options [Integer] :limit the maximum number of records to return (Conjur may return fewer)
|
85
|
+
# @option options [Integer] :offset offset of the first record to return
|
86
|
+
# @option options [Boolean] :count return a count of records instead of the records themselves when set to true
|
139
87
|
# @return [Array<Conjur::Resource>] the resources matching the criteria given
|
140
|
-
def resources
|
141
|
-
|
142
|
-
|
88
|
+
def resources options = {}
|
89
|
+
options = { host: Conjur.configuration.core_url, credentials: credentials }.merge options
|
90
|
+
options[:account] ||= Conjur.configuration.account
|
143
91
|
|
144
|
-
|
92
|
+
host, credentials, account, kind = options.values_at(*[:host, :credentials, :account, :kind])
|
93
|
+
fail ArgumentError, "host and account are required" unless [host, account].all?
|
94
|
+
%w(host credentials account kind).each do |name|
|
95
|
+
options.delete(name.to_sym)
|
96
|
+
end
|
97
|
+
|
98
|
+
credentials ||= {}
|
99
|
+
|
100
|
+
path = "/resources/#{path_escape account}"
|
101
|
+
path += "/#{path_escape kind}" if kind
|
102
|
+
|
103
|
+
result = JSON.parse(RestClient::Resource.new(Conjur.configuration.core_url, credentials)[path][options_querystring options].get)
|
104
|
+
|
105
|
+
result = result['count'] if result.is_a?(Hash)
|
106
|
+
|
145
107
|
if result.is_a?(Numeric)
|
146
108
|
result
|
147
109
|
else
|
@@ -152,51 +114,5 @@ module Conjur
|
|
152
114
|
end
|
153
115
|
end
|
154
116
|
end
|
155
|
-
|
156
|
-
# The resource which grants global privileges to Conjur.
|
157
|
-
# Privileges given on this resource apply to any record in the system.
|
158
|
-
# There are two defined global privileges:
|
159
|
-
#
|
160
|
-
# * **elevate** permission is granted for any action.
|
161
|
-
# * **reveal** methods which list records will always return every matching
|
162
|
-
# record, regardless of whether the user has any privileges on these records or not.
|
163
|
-
# Services can also choose to attach additional semantics to *reveal*, such as allowing
|
164
|
-
# the user to show non-sensitive attributes of any record.
|
165
|
-
#
|
166
|
-
# Global privileges are available in Conjur 4.5 and later.
|
167
|
-
GLOBAL_PRIVILEGE_RESOURCE = "!:!:conjur"
|
168
|
-
|
169
|
-
# Checks whether the client has a particular global privilege.
|
170
|
-
# The global privileges are *elevate* and *reveal*.
|
171
|
-
def global_privilege_permitted? privilege
|
172
|
-
resource(GLOBAL_PRIVILEGE_RESOURCE).permitted? privilege
|
173
|
-
end
|
174
|
-
|
175
|
-
# Check to see if the logged-in role has the specified +privilege+
|
176
|
-
# on the resources specified by +kind+ and +identifiers+.
|
177
|
-
#
|
178
|
-
# @example
|
179
|
-
# secret1 = api.create_variable 'text/plain', 'secret1', id: 'secret1', value: 'my_first_secret'
|
180
|
-
# secret2 = api.create_variable 'text/plain', 'secret2', id: 'secret2', value: 'another_secret'
|
181
|
-
# all_permitted, results = api.resources_permitted? 'variable', ['secret1', 'secret2'], 'execute'
|
182
|
-
|
183
|
-
# @param [String] kind the kind of resources to check
|
184
|
-
# @param [Array<String>] identifiers the (unqualified) identifiers of the resources
|
185
|
-
# @param [String] privilege the privilege to check for
|
186
|
-
# @return [Array] first element is a Boolean, true if all checks passed, false otherwise.
|
187
|
-
# If some checks fail, second element is the check result for each resource.
|
188
|
-
def resources_permitted? kind, identifiers, privilege
|
189
|
-
options = {
|
190
|
-
privilege: privilege,
|
191
|
-
identifiers: identifiers
|
192
|
-
}
|
193
|
-
resp = RestClient::Resource.new(Conjur::Authz::API.host, credentials)["#{Conjur.account}/resources/#{kind}?check=true"].post(options)
|
194
|
-
if resp.code == 204
|
195
|
-
[true, []]
|
196
|
-
else
|
197
|
-
[false, JSON.parse(resp.body)]
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
117
|
end
|
202
118
|
end
|
data/lib/conjur/api/roles.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
|
@@ -19,82 +19,26 @@
|
|
19
19
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
20
|
#
|
21
21
|
require 'conjur/role'
|
22
|
-
require 'conjur/graph'
|
23
22
|
|
24
23
|
module Conjur
|
25
24
|
class API
|
26
|
-
|
25
|
+
include BuildObject
|
27
26
|
|
28
|
-
|
29
|
-
# and follow the normal permissions for role visibility.
|
30
|
-
#
|
31
|
-
# @param [Array<Conjur::Role, String>, String, Conjur::Role] roles role or or array of roles
|
32
|
-
# roles whose relationships we're interested in
|
33
|
-
# @param [Hash] options options for the request
|
34
|
-
# @option options [Boolean] :ancestors Whether to return ancestors ("roles that your role has") of the given roles (true by default)
|
35
|
-
# @option options [Boolean] :descendants Whether to return descendants ("roles that have your role") of the given roles (true by default)
|
36
|
-
# @option options [Conjur::Role, String] :as_role Only roles visible to this role will be included in the graph
|
37
|
-
# @return [Conjur::Graph] An object representing the role memberships digraph
|
38
|
-
def role_graph roles, options = {}
|
39
|
-
roles = [roles] unless roles.kind_of? Array
|
40
|
-
roles.map!{|r| normalize_roleid(r) }
|
41
|
-
options[:as_role] = normalize_roleid(options[:as_role]) if options.include?(:as_role)
|
42
|
-
options.reverse_merge! as_role: normalize_roleid(current_role), descendants: true, ancestors: true
|
43
|
-
|
44
|
-
query = {from_role: options.delete(:as_role)}
|
45
|
-
.merge(options.slice(:ancestors, :descendants))
|
46
|
-
.merge(roles: roles).to_query
|
47
|
-
Conjur::Graph.new RestClient::Resource.new(Conjur::Authz::API.host, credentials)["#{Conjur.account}/roles?#{query}"].get
|
48
|
-
end
|
49
|
-
|
50
|
-
# Create a {Conjur::Role} with the given id.
|
51
|
-
#
|
52
|
-
# ### Permissions
|
53
|
-
# * All Conjur roles can create new roles.
|
54
|
-
# * The creator role (either the current role or the role given by the `:acting_as` option)
|
55
|
-
# is made a member of the new role. The new role is also made a member of itself.
|
56
|
-
# * If you give an `:acting_as` option, you must be a (transitive) member of the `:acting_as`
|
57
|
-
# role.
|
58
|
-
# * The new role is granted to the creator role with *admin option*: that is, the creator role
|
59
|
-
# is able to grant the created role to other roles.
|
60
|
-
#
|
61
|
-
# @example Basic role creation
|
62
|
-
# # Current role is 'user:jon', assume the organizational account is 'conjur'
|
63
|
-
# api.current_role # => 'conjur:user:jon'
|
64
|
-
#
|
65
|
-
# # Create a Conjur actor to control the permissions of a chron job (rebuild_indices)
|
66
|
-
# role = api.create_role 'robot:rebuild_indices'
|
67
|
-
# role.role_id # => "conjur:robot:rebuild_indices"
|
68
|
-
# role.members.map{ |grant| grant.member.role_id } # => ['conjur:user:jon', 'conjur:robot:rebuild_indices']
|
69
|
-
# api.role('user:jon').admin_of?(role) # => true
|
70
|
-
#
|
71
|
-
#
|
72
|
-
# @param [String] role a qualified role identifier for the new role
|
73
|
-
# @param [Hash] options options for the action
|
74
|
-
# @option options [String] :acting_as the resource will effectively be created by this role
|
75
|
-
# @return [Conjur::Role] the created role
|
76
|
-
# @raise [RestClient::MethodNotAllowed] if the role already exists. Note that this differs from
|
77
|
-
# the `RestClient::Conflict` exception raised when trying to create existing high level (user, group, etc.)
|
78
|
-
# Conjur assets.
|
79
|
-
def create_role(role, options = {})
|
80
|
-
role(role).tap do |r|
|
81
|
-
r.create(options)
|
82
|
-
end
|
83
|
-
end
|
27
|
+
#@!group Roles
|
84
28
|
|
85
29
|
# Return a {Conjur::Role} representing a role with the given id. Note that the {Conjur::Role} may or
|
86
30
|
# may not exist (see {Conjur::Exists#exists?}).
|
87
31
|
#
|
88
32
|
# ### Permissions
|
33
|
+
#
|
89
34
|
# Because this method returns roles that may or may not exist, it doesn't require any permissions to call it:
|
90
35
|
# in fact, it does not perform an HTTP request (except for authentication if necessary).
|
91
36
|
#
|
92
37
|
# @example Create and show a role
|
93
|
-
# api.create_role 'cat:iggy'
|
94
38
|
# iggy = api.role 'cat:iggy'
|
95
39
|
# iggy.exists? # true
|
96
|
-
# iggy.members.map(&:member).map(&:
|
97
|
-
# api.current_role.
|
40
|
+
# iggy.members.map(&:member).map(&:id) # => ['conjur:user:admin']
|
41
|
+
# api.current_role.id # => 'conjur:user:admin' # creator role is a member of created role.
|
98
42
|
#
|
99
43
|
# @example No permissions are required to call this method
|
100
44
|
# api.current_role # => "user:no-access"
|
@@ -105,70 +49,49 @@ module Conjur
|
|
105
49
|
# admin.exists? # => true
|
106
50
|
# admin.members # => RestClient::Forbidden: 403 Forbidden
|
107
51
|
#
|
108
|
-
# @param [String]
|
52
|
+
# @param id [String] a fully qualified role identifier
|
109
53
|
# @return [Conjur::Role] an object representing the role
|
110
|
-
def role
|
111
|
-
|
54
|
+
def role id
|
55
|
+
build_object id, default_class: Role
|
112
56
|
end
|
113
57
|
|
114
|
-
# Return a {Conjur::Role} object representing the role (typically a user or host) that this
|
58
|
+
# Return a {Conjur::Role} object representing the role (typically a user or host) that this API instance is authenticated
|
115
59
|
# as. This is derived either from the `login` argument to {Conjur::API.new_from_key} or from the contents of the
|
116
|
-
# `token` given to {Conjur::API.new_from_token}.
|
60
|
+
# `token` given to {Conjur::API.new_from_token} or {Conjur::API.new_from_token_file}.
|
117
61
|
#
|
118
62
|
# @example Current role for a user
|
119
63
|
# api = Conjur::API.new_from_key 'jon', 'somepassword'
|
120
|
-
# api.current_role.
|
64
|
+
# api.current_role.id # => 'conjur:user:jon'
|
121
65
|
#
|
122
66
|
# @example Current role for a host
|
123
67
|
# host = api.create_host id: 'exapmle-host'
|
124
68
|
#
|
125
69
|
# # Host and User have an `api` method that returns an api with their credentials. Note
|
126
70
|
# # that this only works with a newly created host or user, which has an `api_key` attribute.
|
127
|
-
# host.api.current_role.
|
71
|
+
# host.api.current_role.id # => 'conjur:host:example-host'
|
128
72
|
#
|
73
|
+
# @param [String] account the organization account
|
129
74
|
# @return [Conjur::Role] the authenticated role for this API instance
|
130
|
-
def current_role
|
131
|
-
role_from_username username
|
75
|
+
def current_role account
|
76
|
+
self.class.role_from_username self, username, account
|
132
77
|
end
|
133
78
|
|
134
79
|
#@!endgroup
|
135
80
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
# @return [Conjur::Role]
|
141
|
-
def role_from_username username
|
142
|
-
role(role_name_from_username username)
|
143
|
-
end
|
144
|
-
|
145
|
-
# @api private
|
146
|
-
#
|
147
|
-
# Convert a username or host id to a role identifier.
|
148
|
-
# This handles conversion of logins like 'host/foo' to 'host:foo'
|
149
|
-
# @param [String] username the user name or host id
|
150
|
-
# @return [String] A full role id for the user or host
|
151
|
-
def role_name_from_username username = self.username
|
152
|
-
tokens = username.split('/')
|
153
|
-
if tokens.size == 1
|
154
|
-
[ 'user', username ].join(':')
|
155
|
-
else
|
156
|
-
[ tokens[0], tokens[1..-1].join('/') ].join(':')
|
81
|
+
class << self
|
82
|
+
# @api private
|
83
|
+
def role_from_username api, username, account
|
84
|
+
api.role role_name_from_username(username, account)
|
157
85
|
end
|
158
|
-
end
|
159
|
-
|
160
|
-
private
|
161
86
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
when Role then role.roleid
|
171
|
-
else raise "Can't normalize #{role}@#{role.class}"
|
87
|
+
# @api private
|
88
|
+
def role_name_from_username username, account
|
89
|
+
tokens = username.split('/')
|
90
|
+
if tokens.size == 1
|
91
|
+
[ account, 'user', username ].join(':')
|
92
|
+
else
|
93
|
+
[ account, tokens[0], tokens[1..-1].join('/') ].join(':')
|
94
|
+
end
|
172
95
|
end
|
173
96
|
end
|
174
97
|
end
|
data/lib/conjur/api/variables.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,54 +22,8 @@ require 'conjur/variable'
|
|
22
22
|
|
23
23
|
module Conjur
|
24
24
|
class API
|
25
|
-
|
26
|
-
|
27
|
-
# Create a {http://developer.conjur.net/reference/services/directory/variable Conjur Variable}.
|
28
|
-
# See {Conjur::Variable} for operations on Conjur variables.
|
29
|
-
#
|
30
|
-
# ### Permissions
|
31
|
-
# Any authenticated role may call this method
|
32
|
-
#
|
33
|
-
# @example Create a variable to store a database connection string
|
34
|
-
# db_uri = "mysql://username:password@mysql.somehost.com/mydb"
|
35
|
-
# var = api.create_variable 'text/plain', 'mysql-connection-string', id: 'production/mysql/uri'
|
36
|
-
# var.add_value db_uri
|
37
|
-
#
|
38
|
-
# # Alternatively, we could have done this:
|
39
|
-
# var = api.create_variable 'text/plain', 'mysql-connection-string',
|
40
|
-
# id: 'production/mysql/uri',
|
41
|
-
# value: db_uri
|
42
|
-
#
|
43
|
-
# @example Create a variable with a unique random id
|
44
|
-
# var = api.create_variable 'text/plain', 'secret'
|
45
|
-
# var.id # => 'kngeqg'
|
46
|
-
#
|
47
|
-
# @param [String] mime_type MIME type for the variable value, used to set the `"Content-Type"`header
|
48
|
-
# when serving the variable's value. Must be non-empty.
|
49
|
-
# @param [String] kind user defined `kind` for the variable. This is useful as a simple way to document
|
50
|
-
# the variable's purpose. Must be non-empty
|
51
|
-
# @param [Hash] options options for the new variable
|
52
|
-
# @option options [String] :id specify an id for the new variable. Must be non-empty.
|
53
|
-
# @option options [String] :value specify an initial value for the variable
|
54
|
-
# @return [Conjur::Variable] an object representing the new variable
|
55
|
-
# @raise [RestClient::Conflict] if you give an `:id` option and the variable already exists
|
56
|
-
# @raise [RestClient::UnprocessableEntity] if `mime_type`, `kind`, or `options[:id]` is the empty string.
|
57
|
-
def create_variable(mime_type, kind, options = {})
|
58
|
-
standard_create Conjur::Core::API.host, :variable, nil, options.merge(mime_type: mime_type, kind: kind)
|
59
|
-
end
|
60
|
-
|
61
|
-
# Retrieve an object representing a {http://developer.conjur.net/reference/services/directory/variable Conjur Variable}.
|
62
|
-
# The {Conjur::Variable} returned may or may not exist, and
|
63
|
-
# your permissions on the corresponding resource determine the operations you can perform on it.
|
64
|
-
#
|
65
|
-
# ### Permissions
|
66
|
-
# Any authenticated role can call this method.
|
67
|
-
#
|
68
|
-
# @param [String] id the unqualified id of the variable
|
69
|
-
# @return [Conjur::Variable] and object representing the variable.
|
70
|
-
def variable id
|
71
|
-
standard_show Conjur::Core::API.host, :variable, id
|
72
|
-
end
|
25
|
+
|
26
|
+
#@!group Variables
|
73
27
|
|
74
28
|
# Fetch the values of a list of variables. This operation is more efficient than fetching the
|
75
29
|
# values one by one.
|
@@ -79,56 +33,33 @@ module Conjur
|
|
79
33
|
# * You have permission to `'execute'` all of the variables
|
80
34
|
#
|
81
35
|
# @example Fetch multiple variable values
|
82
|
-
# values = variable_values ['postgres_uri', 'aws_secret_access_key', 'aws_access_key_id']
|
36
|
+
# values = variable_values ['myorg:variable:postgres_uri', 'myorg:variable:aws_secret_access_key', 'myorg:variable:aws_access_key_id']
|
83
37
|
# values # =>
|
84
38
|
# {
|
85
|
-
# "
|
86
|
-
# "
|
87
|
-
# "
|
39
|
+
# "postgres://...",
|
40
|
+
# "the-secret-key",
|
41
|
+
# "the-access-key-id"
|
88
42
|
# }
|
89
|
-
#
|
43
|
+
#
|
90
44
|
# This method is used to implement the {http://developer.conjur.net/reference/tools/utilities/conjurenv `conjur env`}
|
91
45
|
# commands. You may consider using that instead to run your program in an environment with the necessary secrets.
|
92
46
|
#
|
93
|
-
# @param [Array<String>]
|
94
|
-
# @return [
|
47
|
+
# @param [Array<String>] variable_ids list of variable ids to fetch
|
48
|
+
# @return [Array<String>] a list of variable values corresponding to the variable ids.
|
95
49
|
# @raise [RestClient::Forbidden, RestClient::ResourceNotFound] if any of the variables don't exist or aren't accessible.
|
96
|
-
def variable_values
|
97
|
-
raise ArgumentError, "Variables list must be an array" unless
|
98
|
-
raise ArgumentError, "Variables list is empty" if
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
50
|
+
def variable_values variable_ids
|
51
|
+
raise ArgumentError, "Variables list must be an array" unless variable_ids.kind_of? Array
|
52
|
+
raise ArgumentError, "Variables list is empty" if variable_ids.empty?
|
53
|
+
|
54
|
+
opts = "?variable_ids=#{variable_ids.map { |v| fully_escape(v) }.join(',')}"
|
55
|
+
|
56
|
+
response =
|
57
|
+
RestClient::Resource.
|
58
|
+
new(Conjur.configuration.core_url,credentials)['secrets'+opts].get
|
59
|
+
|
60
|
+
return JSON.parse(response.body)
|
106
61
|
end
|
107
|
-
|
108
|
-
# Fetch all visible variables that expire within the given
|
109
|
-
# interval (relative to the current time on the Conjur Server). If
|
110
|
-
# no interval is specifed, all variables that are set to expire
|
111
|
-
# will be returned.
|
112
|
-
#
|
113
|
-
# interval should either be a String containing an ISO8601
|
114
|
-
# duration, or it should implement #to_i to return a number of
|
115
|
-
# seconds.
|
116
|
-
#
|
117
|
-
# @example Use an ISO8601 duration to return variables expiring in the next month
|
118
|
-
# expirations = api.variable_expirations('P1M')
|
119
|
-
#
|
120
|
-
# @example Use ActiveSupport to return variables expiring in the next month
|
121
|
-
# require 'active_support/all'
|
122
|
-
# expirations = api.variable_expirations(1.month)
|
123
|
-
|
124
|
-
# param interval a String containing an ISO8601 duration , or a number of seconds
|
125
|
-
# return [Hash] variable expirations that occur within the interval
|
126
|
-
def variable_expirations(interval = nil)
|
127
|
-
duration = interval.try { |i| i.respond_to?(:to_str) ? i : "PT#{i.to_i}S" }
|
128
|
-
params = {}.tap { |p| p.merge!({:params => {:duration => duration }}) if duration }
|
129
|
-
JSON.parse(RestClient::Resource.new(Conjur::Core::API.host, self.credentials)['variables/expirations'].get(params).body)
|
130
|
-
end
|
131
|
-
|
62
|
+
|
132
63
|
#@!endgroup
|
133
64
|
end
|
134
65
|
end
|
data/lib/conjur/api.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
|
@@ -21,36 +21,36 @@
|
|
21
21
|
require 'active_support'
|
22
22
|
require 'active_support/deprecation'
|
23
23
|
|
24
|
-
require 'conjur/cast'
|
25
24
|
require 'conjur/configuration'
|
26
|
-
require 'conjur/
|
25
|
+
require 'conjur/id'
|
27
26
|
require 'conjur/base'
|
28
27
|
require 'conjur/exceptions'
|
29
|
-
require 'conjur/
|
28
|
+
require 'conjur/build_object'
|
29
|
+
require 'conjur/base_object'
|
30
30
|
require 'conjur/acts_as_resource'
|
31
31
|
require 'conjur/acts_as_role'
|
32
|
+
require 'conjur/acts_as_rolsource'
|
32
33
|
require 'conjur/acts_as_user'
|
33
34
|
require 'conjur/log_source'
|
34
35
|
require 'conjur/has_attributes'
|
35
|
-
require 'conjur/
|
36
|
-
require 'conjur/
|
37
|
-
require 'conjur/
|
38
|
-
require 'conjur/
|
39
|
-
require 'conjur/
|
40
|
-
require 'conjur/
|
41
|
-
require 'conjur/
|
42
|
-
require 'conjur/
|
43
|
-
require 'conjur/
|
44
|
-
require 'conjur/
|
45
|
-
require 'conjur/
|
36
|
+
require 'conjur/api/authn'
|
37
|
+
require 'conjur/api/roles'
|
38
|
+
require 'conjur/api/resources'
|
39
|
+
require 'conjur/api/pubkeys'
|
40
|
+
require 'conjur/api/variables'
|
41
|
+
require 'conjur/api/policies'
|
42
|
+
require 'conjur/api/host_factories'
|
43
|
+
require 'conjur/host'
|
44
|
+
require 'conjur/group'
|
45
|
+
require 'conjur/variable'
|
46
|
+
require 'conjur/layer'
|
46
47
|
require 'conjur/cache'
|
47
48
|
require 'conjur-api/version'
|
48
|
-
require 'conjur/api/info'
|
49
|
-
require 'conjur/api/ldapsync'
|
50
49
|
|
51
50
|
# Monkey patch RestClient::Request so it always uses
|
52
51
|
# :ssl_cert_store. (RestClient::Resource uses Request to send
|
53
52
|
# requests, so it sees :ssl_cert_store, too).
|
53
|
+
# @api private
|
54
54
|
class RestClient::Request
|
55
55
|
alias_method :initialize_without_defaults, :initialize
|
56
56
|
|
@@ -63,24 +63,12 @@ class RestClient::Request
|
|
63
63
|
def initialize args
|
64
64
|
initialize_without_defaults default_args.merge(args)
|
65
65
|
end
|
66
|
-
|
67
66
|
end
|
68
67
|
|
69
|
-
|
68
|
+
# @api private
|
70
69
|
class RestClient::Resource
|
71
70
|
include Conjur::Escape
|
72
71
|
include Conjur::LogSource
|
73
|
-
include Conjur::Cast
|
74
|
-
extend Conjur::BuildFromResponse
|
75
|
-
|
76
|
-
# @api private
|
77
|
-
# @deprecated
|
78
|
-
# The account used by the core service. This is deprecated in favor of {Conjur.account} and
|
79
|
-
# {Conjur::Configuration#account}.
|
80
|
-
# @return [String] the core account
|
81
|
-
def core_conjur_account
|
82
|
-
Conjur::Core::API.conjur_account
|
83
|
-
end
|
84
72
|
|
85
73
|
# @api private
|
86
74
|
# This method exists so that all {RestClient::Resource}s support JSON serialization. It returns an
|
@@ -98,10 +86,7 @@ class RestClient::Resource
|
|
98
86
|
#
|
99
87
|
# @return {Conjur::API} the new api
|
100
88
|
def conjur_api
|
101
|
-
api = Conjur::API.new_from_token token, remote_ip
|
102
|
-
api = api.with_privilege(conjur_privilege) if conjur_privilege
|
103
|
-
api = api.with_audit_roles(audit_roles) if audit_roles
|
104
|
-
api = api.with_audit_resources(audit_resources) if audit_resources
|
89
|
+
api = Conjur::API.new_from_token token, remote_ip: remote_ip
|
105
90
|
api
|
106
91
|
end
|
107
92
|
|
@@ -126,18 +111,6 @@ class RestClient::Resource
|
|
126
111
|
options[:headers][:x_forwarded_for]
|
127
112
|
end
|
128
113
|
|
129
|
-
def conjur_privilege
|
130
|
-
options[:headers][:x_conjur_privilege]
|
131
|
-
end
|
132
|
-
|
133
|
-
def audit_roles
|
134
|
-
options[:headers][:conjur_audit_roles].try { |r| Conjur::API.decode_audit_ids(r) }
|
135
|
-
end
|
136
|
-
|
137
|
-
def audit_resources
|
138
|
-
options[:headers][:conjur_audit_resources].try { |r| Conjur::API.decode_audit_ids(r) }
|
139
|
-
end
|
140
|
-
|
141
114
|
# The username this resource authenticates as.
|
142
115
|
#
|
143
116
|
# @return [String] the username
|