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.
Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +1 -0
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +22 -3
  5. data/Dockerfile +12 -3
  6. data/Gemfile +3 -3
  7. data/Jenkinsfile +69 -0
  8. data/LICENSE.md +195 -0
  9. data/README.md +16 -0
  10. data/Rakefile +34 -18
  11. data/ci/wait_for_server.sh +10 -0
  12. data/conjur-api.gemspec +6 -14
  13. data/dev/docker-compose.yml +23 -0
  14. data/dev/empty.yml +2 -0
  15. data/dev/start.sh +15 -0
  16. data/dev/stop.sh +6 -0
  17. data/docker-compose.yml +27 -0
  18. data/features/exists.feature +37 -0
  19. data/features/group.feature +11 -0
  20. data/features/host.feature +20 -0
  21. data/features/host_factory_create_host.feature +28 -0
  22. data/features/host_factory_token.feature +63 -0
  23. data/features/load_policy.feature +61 -0
  24. data/features/members.feature +51 -0
  25. data/features/new_api.feature +36 -0
  26. data/features/permitted.feature +43 -0
  27. data/features/permitted_roles.feature +30 -0
  28. data/features/public_keys.feature +11 -0
  29. data/features/resource_fields.feature +53 -0
  30. data/features/role_fields.feature +15 -0
  31. data/features/rotate_api_key.feature +13 -0
  32. data/features/step_definitions/api_steps.rb +4 -54
  33. data/features/step_definitions/policy_steps.rb +35 -0
  34. data/features/step_definitions/result_steps.rb +7 -0
  35. data/features/support/env.rb +14 -5
  36. data/features/support/hooks.rb +3 -0
  37. data/features/support/world.rb +5 -6
  38. data/features/update_password.feature +14 -0
  39. data/features/user.feature +17 -0
  40. data/features/variable_fields.feature +20 -0
  41. data/features/variable_value.feature +67 -0
  42. data/lib/conjur/acts_as_resource.rb +95 -65
  43. data/lib/conjur/acts_as_role.rb +102 -51
  44. data/lib/conjur/{audit-api.rb → acts_as_rolsource.rb} +10 -14
  45. data/lib/conjur/acts_as_user.rb +13 -22
  46. data/lib/conjur/api/authn.rb +37 -72
  47. data/lib/conjur/api/host_factories.rb +35 -55
  48. data/lib/conjur/api/policies.rb +56 -0
  49. data/lib/conjur/api/pubkeys.rb +36 -160
  50. data/lib/conjur/api/resources.rb +32 -116
  51. data/lib/conjur/api/roles.rb +28 -105
  52. data/lib/conjur/api/variables.rb +22 -91
  53. data/lib/conjur/api.rb +19 -46
  54. data/lib/conjur/base.rb +21 -132
  55. data/lib/conjur/base_object.rb +57 -0
  56. data/lib/conjur/{authn-api.rb → build_object.rb} +23 -11
  57. data/lib/conjur/cast.rb +12 -17
  58. data/lib/conjur/cert_utils.rb +1 -1
  59. data/lib/conjur/cidr.rb +1 -1
  60. data/lib/conjur/configuration.rb +13 -91
  61. data/lib/conjur/escape.rb +1 -2
  62. data/lib/conjur/group.rb +9 -65
  63. data/lib/conjur/has_attributes.rb +22 -59
  64. data/lib/conjur/host.rb +5 -35
  65. data/lib/conjur/host_factory.rb +40 -40
  66. data/lib/conjur/host_factory_token.rb +38 -23
  67. data/lib/conjur/id.rb +63 -0
  68. data/lib/conjur/layer.rb +5 -80
  69. data/lib/conjur/log.rb +1 -1
  70. data/lib/conjur/log_source.rb +1 -1
  71. data/lib/conjur/{secret.rb → policy.rb} +11 -14
  72. data/lib/conjur/{api/secrets.rb → policy_load_result.rb} +35 -22
  73. data/lib/conjur/query_string.rb +2 -1
  74. data/lib/conjur/resource.rb +5 -299
  75. data/lib/conjur/role.rb +5 -317
  76. data/lib/conjur/role_grant.rb +20 -28
  77. data/lib/conjur/user.rb +5 -63
  78. data/lib/conjur/variable.rb +31 -76
  79. data/lib/conjur/{authz-api.rb → webservice.rb} +8 -16
  80. data/lib/conjur-api/version.rb +2 -2
  81. data/publish.sh +7 -0
  82. data/spec/api_spec.rb +208 -0
  83. data/spec/cast_spec.rb +21 -0
  84. data/spec/{lib/cert_utils_spec.rb → cert_utils_spec.rb} +0 -0
  85. data/spec/{lib/cidr_spec.rb → cidr_spec.rb} +0 -0
  86. data/spec/{lib/configuration_spec.rb → configuration_spec.rb} +40 -140
  87. data/spec/{lib/has_attributes_spec.rb → has_attributes_spec.rb} +6 -2
  88. data/spec/{lib/log_source_spec.rb → log_source_spec.rb} +0 -0
  89. data/spec/{lib/log_spec.rb → log_spec.rb} +0 -0
  90. data/spec/roles_spec.rb +24 -0
  91. data/spec/spec_helper.rb +63 -78
  92. data/spec/ssl_spec.rb +3 -5
  93. data/spec/vendor/rest_client_spec.rb +0 -54
  94. data/test.sh +40 -0
  95. metadata +122 -281
  96. data/.kateproject +0 -5
  97. data/LICENSE +0 -22
  98. data/ci/test.sh +0 -9
  99. data/features/audit_resources.feature +0 -15
  100. data/features/audit_roles.feature +0 -15
  101. data/features/bootstrap.feature +0 -31
  102. data/features/step_definitions/cli_steps.rb +0 -5
  103. data/jenkins.sh +0 -27
  104. data/lib/conjur/acts_as_asset.rb +0 -88
  105. data/lib/conjur/annotations.rb +0 -186
  106. data/lib/conjur/api/audit.rb +0 -138
  107. data/lib/conjur/api/deputies.rb +0 -57
  108. data/lib/conjur/api/groups.rb +0 -111
  109. data/lib/conjur/api/hosts.rb +0 -109
  110. data/lib/conjur/api/info.rb +0 -126
  111. data/lib/conjur/api/layers.rb +0 -62
  112. data/lib/conjur/api/ldapsync.rb +0 -115
  113. data/lib/conjur/api/users.rb +0 -106
  114. data/lib/conjur/bootstrap.rb +0 -161
  115. data/lib/conjur/build_from_response.rb +0 -49
  116. data/lib/conjur/core-api.rb +0 -74
  117. data/lib/conjur/deputy.rb +0 -55
  118. data/lib/conjur/env.rb +0 -54
  119. data/lib/conjur/event_source.rb +0 -101
  120. data/lib/conjur/exists.rb +0 -60
  121. data/lib/conjur/graph.rb +0 -295
  122. data/lib/conjur/has_id.rb +0 -43
  123. data/lib/conjur/has_identifier.rb +0 -36
  124. data/lib/conjur/has_owner.rb +0 -51
  125. data/lib/conjur/host-factory-api.rb +0 -38
  126. data/lib/conjur/layer-api.rb +0 -13
  127. data/lib/conjur/ldap_sync_job.rb +0 -89
  128. data/lib/conjur/path_based.rb +0 -86
  129. data/lib/conjur/pubkeys-api.rb +0 -50
  130. data/lib/conjur/standard_methods.rb +0 -91
  131. data/reqspeed.rb +0 -20
  132. data/spec/api/authn_spec.rb +0 -81
  133. data/spec/api/graph_spec.rb +0 -117
  134. data/spec/api/groups_spec.rb +0 -40
  135. data/spec/api/hosts_spec.rb +0 -36
  136. data/spec/api/info_spec.rb +0 -89
  137. data/spec/api/layer_spec.rb +0 -18
  138. data/spec/api/ldapsync_spec.rb +0 -44
  139. data/spec/api/pubkeys_spec.rb +0 -66
  140. data/spec/api/resources_spec.rb +0 -92
  141. data/spec/api/roles_spec.rb +0 -100
  142. data/spec/api/secrets_spec.rb +0 -16
  143. data/spec/api/users_spec.rb +0 -71
  144. data/spec/api/variables_spec.rb +0 -112
  145. data/spec/cas_rest_client.rb +0 -17
  146. data/spec/cidr_helper.rb +0 -24
  147. data/spec/lib/acts_as_user_spec.rb +0 -27
  148. data/spec/lib/annotations_spec.rb +0 -109
  149. data/spec/lib/api_spec.rb +0 -480
  150. data/spec/lib/asset_spec.rb +0 -80
  151. data/spec/lib/audit_spec.rb +0 -155
  152. data/spec/lib/build_from_response_spec.rb +0 -49
  153. data/spec/lib/deputy_spec.rb +0 -25
  154. data/spec/lib/exists_spec.rb +0 -24
  155. data/spec/lib/group_spec.rb +0 -18
  156. data/spec/lib/host_spec.rb +0 -31
  157. data/spec/lib/resource_spec.rb +0 -240
  158. data/spec/lib/role_grant_spec.rb +0 -13
  159. data/spec/lib/role_spec.rb +0 -231
  160. data/spec/lib/standard_methods_spec.rb +0 -66
  161. data/spec/lib/user_spec.rb +0 -77
  162. data/spec/standard_methods_helper.rb +0 -41
  163. data/spec/variable_spec.rb +0 -101
  164. data/spec/vcr_cassettes/Conjur_Resource/_create/with_path-like_identifier.yml +0 -87
  165. data/spec/vcr_cassettes/Conjur_Resource/_create/with_un-encoded_path-like_identifier.yml +0 -87
  166. data/spec/vcr_cassettes/Conjur_Resource/_create/with_uuid_identifier.yml +0 -87
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013 Conjur Inc
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
@@ -18,31 +18,44 @@
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
- require 'conjur/secret'
22
-
23
21
  module Conjur
24
- class API
25
-
22
+ # The result of loading a policy. When a policy is loaded, two types of data
23
+ # are always provided:
24
+ #
25
+ # * {#created_roles} the API keys of any new roles which were created
26
+ # * {#version} the new version of the policy.
27
+ class PolicyLoadResult
28
+ def initialize data
29
+ @data = data
30
+ end
31
+
26
32
  # @api private
27
- #
28
- # Create a Conjur secret. Secrets are a low-level construcct upon which variables
29
- # are built,
30
- #
31
- # @param [String] value the secret data
32
- # @return [Conjur::Secret] the new secret
33
- def create_secret(value, options = {})
34
- standard_create Conjur::Core::API.host, :secret, nil, options.merge(value: value)
33
+ def to_h
34
+ @data
35
35
  end
36
-
36
+
37
37
  # @api private
38
+ def to_json options = {}
39
+ @data.to_json(options)
40
+ end
41
+
42
+ # @api private
43
+ def to_s
44
+ @data.to_s
45
+ end
46
+
47
+ # API keys for roles which were created when loading the policy.
38
48
  #
39
- # Fetch a Conjur secret by id. Secrets are a low-level construct upon which variables
40
- # are built, and should not generally be used directly.
41
- #
42
- # @param [String] id the *unqualified* identifier for the secret
43
- # @return [Conjur::Secret] an object representing the secret
44
- def secret id
45
- standard_show Conjur::Core::API.host, :secret, id
49
+ # @return [Hash] Hash keys are the role ids, and hash values are the API keys.
50
+ def created_roles
51
+ @data['created_roles']
52
+ end
53
+
54
+ # The new version of the policy. When a policy is updated, a new version is appended
55
+ # to that policy. The YAML of previous versions of the policy can be obtained
56
+ # by fetching the policy resource using {API#resource}.
57
+ def version
58
+ @data['version']
46
59
  end
47
60
  end
48
- end
61
+ end
@@ -1,4 +1,5 @@
1
- module QueryString
1
+ # @api private
2
+ module Conjur::QueryString
2
3
  protected
3
4
 
4
5
  def options_querystring options
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013 Conjur Inc
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
@@ -18,306 +18,12 @@
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
- require 'conjur/annotations'
22
21
 
23
22
  module Conjur
24
23
 
25
- # A `Conjur::Resource` instance represents a Conjur
26
- # {http://developer.conjur.net/reference/services/authorization/resource Resource}.
27
- #
28
- # You should not instantiate this class directly. Instead, you can get an instance from the
29
- # {Conjur::API#resource} and {Conjur::API#resources} methods, or from the {ActsAsResource#resource} method
30
- # present on objects representing Conjur assets that have associated resources.
31
- #
32
- class Resource < RestClient::Resource
33
- include HasAttributes
34
- include PathBased
35
- include Exists
36
- include QueryString
37
- extend QueryString
38
-
39
- alias resource_kind kind
40
-
41
- # The identifier part of the `resource_id` for this resource. The identifier
42
- # is the resource id without the `account` and `kind` parts.
43
- #
44
- # @example
45
- # resource = api.resource 'conjur:layer:pubkeys-1.0/public-keys'
46
- # resource.identifier # => 'pubkeys-1.0/public-keys'
47
- #
48
- # @return [String] the identifier part of the id.
49
- def identifier
50
- match_path(3..-1)
51
- end
52
-
53
- # The full role id of the role that owns this resource.
54
- #
55
- # @example
56
- # api.current_role # => 'conjur:user:jon'
57
- # resource = api.create_resource 'conjur:example:resource-owner'
58
- # resource.owner # => 'conjur:user:jon'
59
- #
60
- # @return [String] the full role id of this resource's owner.
61
- def ownerid
62
- attributes['owner']
63
- end
64
-
65
- alias owner ownerid
66
-
67
- # Return the full id for this resource. The format is `account:kind:identifier`
68
- #
69
- # @example
70
- # resource = api.layer('pubkeys-1.0/public-keys').resource
71
- # resource.account # => 'conjur'
72
- # resource.kind # => 'layer'
73
- # resource.identifier # => 'pubkeys-1.0/public-keys'
74
- # resource.resourceid # => 'conjur:layer:pubkeys-1.0/public-keys'
75
- # @return [String]
76
- def resourceid
77
- [account, kind, identifier].join ':'
78
- end
79
-
80
- alias :resource_id :resourceid
81
-
82
-
83
- # @api private
84
- def create(options = {})
85
- log do |logger|
86
- logger << "Creating resource #{resourceid}"
87
- unless options.empty?
88
- logger << " with options #{options.to_json}"
89
- end
90
- end
91
- self.put(options)
92
- end
93
-
94
- # Lists roles that have a specified privilege on the resource.
95
- #
96
- # This will return only roles of which api.current_user is a member.
97
- #
98
- # Options:
99
- #
100
- # * **offset** Zero-based offset into the result set.
101
- # * **limit** Total number of records returned.
102
- #
103
- # @example
104
- # resource = api.resource 'conjur:variable:example'
105
- # resource.permitted_roles 'execute' # => ['conjur:user:admin']
106
- # resource.permit 'execute', api.user('jon')
107
- # resource.permitted_roles 'execute' # => ['conjur:user:admin', 'conjur:user:jon']
108
- #
109
- # @param privilege [String] the privilege
110
- # @param options [Hash, nil] extra parameters to pass to the webservice method.
111
- # @return [Array<String>] the ids of roles that have `privilege` on this resource, sorted
112
- # alphabetically.
113
- def permitted_roles(privilege, options = {})
114
- result = JSON.parse RestClient::Resource.new(Conjur::Authz::API.host, self.options)["#{account}/roles/allowed_to/#{privilege}/#{path_escape kind}/#{path_escape identifier}#{options_querystring options}"].get
115
- if result.is_a?(Hash) && ( count = result['count'] )
116
- count
117
- else
118
- result
119
- end
120
- end
121
-
122
- # Changes the owner of a resource. You must be the owner of the resource
123
- # or a member of the owner role to do this.
124
- #
125
- # @example
126
- # resource.owner # => 'conjur:user:admin'
127
- # resource.give_to 'conjur:user:jon'
128
- # resource.owner # => 'conjur:user:jon'
129
- #
130
- # @param owner [String, #roleid] the new owner.
131
- # @return [void]
132
- def give_to(owner, options = {})
133
- owner = cast(owner, :roleid)
134
- invalidate do
135
- self.put(options.merge(owner: owner))
136
- end
137
-
138
- nil
139
- end
140
-
141
- # @api private
142
- def delete(options = {})
143
- log do |logger|
144
- logger << "Deleting resource #{resourceid}"
145
- unless options.empty?
146
- logger << " with options #{options.to_json}"
147
- end
148
- end
149
- super options
150
- end
151
-
152
- # Grant `privilege` on this resource to `role`.
153
- #
154
- # This operation is idempotent, that is, nothing will happen if
155
- # you attempt to grant a privilege that the role already has on
156
- # this resource.
157
- #
158
- # @example
159
- # user = api.user 'bob'
160
- # resource = api.variable('example').resource
161
- # resource.permitted_roles 'bake' # => ['conjur:user:admin']
162
- # resource.permit 'fry', user
163
- # resource.permitted_roles 'fry' # => ['conjur:user:admin', 'conjur:user:bob']
164
- # resource.permit ['boil', 'bake'], bob
165
- # resource.permitted_roles 'boil' # => ['conjur:user:admin', 'conjur:user:bob']
166
- # resource.permitted_roles 'bake' # => ['conjur:user:admin', 'conjur:user:bob']
167
- #
168
- # @param privilege [String, #each] The privilege to grant, for example
169
- # `'execute'`, `'read'`, or `'update'`. You may also pass an `Enumerable`
170
- # object, in which case the Strings yielded by #each will all be granted
171
- #
172
- # @param role [String, #roleid] The role-ish object or full role id
173
- # to which the privilege is to be granted.
174
- #
175
- # @param options [Hash, nil] options to pass through to `RestClient::Resource#post`
176
- #
177
- # @return [void]
178
- def permit(privilege, role, options = {})
179
- role = cast(role, :roleid)
180
- eachable(privilege).each do |p|
181
- log do |logger|
182
- logger << "Permitting #{p} on resource #{resourceid} by #{role}"
183
- unless options.empty?
184
- logger << " with options #{options.to_json}"
185
- end
186
- end
187
-
188
- begin
189
- self["?permit&privilege=#{query_escape p}&role=#{query_escape role}"].post(options)
190
- rescue RestClient::Forbidden
191
- # TODO: Remove once permit is idempotent
192
- raise $! unless $!.http_body == "Privilege already granted."
193
- end
194
- end
195
- nil
196
- end
197
-
198
- # The inverse operation of `#permit`. Deny privilege `privilege` to `role`
199
- # on this resource.
200
- #
201
- # @example
202
- #
203
- # resource.permitted_roles 'execute' # => ['conjur:user:admin', 'conjur:user:alice']
204
- # resource.deny 'execute', 'conjur:user:alice'
205
- # resource.permitted_roles 'execute' # => ['conjur:user:admin']
206
- #
207
- # @param privilege [String, #each] A privilege name or an `Enumerable` of privileges to deny. In the
208
- # later, all privileges will be denied.
209
- #
210
- # @param role [String, :roleid] A full role id or a role-ish object whose privileges we will deny.
211
- #
212
- # @return [void]
213
- def deny(privilege, role, options = {})
214
- role = cast(role, :roleid)
215
- eachable(privilege).each do |p|
216
- log do |logger|
217
- logger << "Denying #{p} on resource #{resourceid} by #{role}"
218
- unless options.empty?
219
- logger << " with options #{options.to_json}"
220
- end
221
- end
222
- self["?deny&privilege=#{query_escape p}&role=#{query_escape role}"].post(options)
223
- end
224
- nil
225
- end
226
-
227
- # True if the logged-in role, or a role specified using the :acting_as option, has the
228
- # specified +privilege+ on this resource.
229
- #
230
- # @example
231
- # api.current_role # => 'conjur:cat:mouse'
232
- # resource.permitted_roles 'execute' # => ['conjur:user:admin', 'conjur:cat:mouse']
233
- # resource.permitted_roles 'update', # => ['conjur:user:admin', 'conjur:cat:gino']
234
- #
235
- # resource.permitted? 'update' # => false, `mouse` can't update this resource
236
- # resource.permitted? 'execute' # => true, `mouse` can execute it.
237
- # resource.permitted? 'update',acting_as: 'conjur:cat:gino' # => true, `gino` can update it.
238
- # @param privilege [String] the privilege to check
239
- # @param [Hash, nil] options for the request
240
- # @option options [String,nil] :acting_as check whether the role given by this full role id is permitted
241
- # instead of checking +api.current_role+.
242
- # @return [Boolean]
243
- def permitted?(privilege, options = {})
244
- # TODO this method should accept an optional role rather than putting it in the options hash.
245
- params = {
246
- check: true,
247
- privilege: query_escape(privilege)
248
- }
249
- params[:acting_as] = options[:acting_as] if options[:acting_as]
250
- self["?#{params.to_query}"].get(options)
251
- true
252
- rescue RestClient::Forbidden
253
- false
254
- rescue RestClient::ResourceNotFound
255
- false
256
- end
257
-
258
- # Return an {Conjur::Annotations} object to manipulate and view annotations.
259
- #
260
- # @see Conjur::Annotations
261
- # @example
262
- # resource.annotations.count # => 0
263
- # resource.annotations['foo'] = 'bar'
264
- # resource.annotations.each do |k,v|
265
- # puts "#{k}=#{v}"
266
- # end
267
- # # output is
268
- # # foo=bar
269
- #
270
- #
271
- # @return [Conjur::Annotations]
272
- def annotations
273
- @annotations ||= Conjur::Annotations.new(self)
274
- end
275
- alias tags annotations
276
-
277
- # @api private
278
- # This is documented by Conjur::API#resources.
279
- # Returns all resources (optionally qualified by kind) visible to the user with given credentials.
280
- #
281
- #
282
- # Options are:
283
- # - host - authz url,
284
- # - credentials,
285
- # - account,
286
- # - owner (optional),
287
- # - kind (optional),
288
- # - search (optional),
289
- # - limit (optional),
290
- # - offset (optional).
291
- def self.all options = {}
292
- host, credentials, account, kind = options.values_at(*[:host, :credentials, :account, :kind])
293
- fail ArgumentError, "host and account are required" unless [host, account].all?
294
- %w(host credentials account kind).each do |name|
295
- options.delete(name.to_sym)
296
- end
297
-
298
- credentials ||= {}
299
-
300
- path = "#{account}/resources"
301
- path += "/#{kind}" if kind
302
-
303
- result = JSON.parse(RestClient::Resource.new(host, credentials)[path][options_querystring options].get)
304
-
305
- result = result['count'] if result.is_a?(Hash)
306
- result
307
- end
308
-
309
- protected
310
-
311
-
312
- # Given an Object, return something that responds to each. In particular,
313
- # if `item.respond_to? :each` is true, we return the item, otherwise we put it in
314
- # an array.
315
- #
316
- # @param item [Object] the value we want to each over.
317
- # @return [#each] `item` if item is already eachable, otherwise `[item]`.
318
- # @api private
319
- def eachable(item)
320
- item.respond_to?(:each) ? item : [ item ]
321
- end
24
+ # A Conjur custom Resource. This object is used for resources whose `kind` is not
25
+ # any of the pre-defined common types such as {Group}, {Host}, {Variable}, etc.
26
+ class Resource < BaseObject
27
+ include ActsAsResource
322
28
  end
323
29
  end