conjur-api 4.14.0 → 4.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/CHANGELOG.md +4 -0
  4. data/lib/conjur-api/version.rb +1 -1
  5. data/lib/conjur/acts_as_asset.rb +44 -3
  6. data/lib/conjur/acts_as_resource.rb +53 -4
  7. data/lib/conjur/acts_as_user.rb +17 -7
  8. data/lib/conjur/annotations.rb +49 -3
  9. data/lib/conjur/api.rb +30 -3
  10. data/lib/conjur/api/deputies.rb +25 -1
  11. data/lib/conjur/api/resources.rb +109 -5
  12. data/lib/conjur/api/roles.rb +103 -11
  13. data/lib/conjur/api/secrets.rb +16 -1
  14. data/lib/conjur/api/users.rb +65 -1
  15. data/lib/conjur/api/variables.rb +65 -1
  16. data/lib/conjur/audit-api.rb +3 -0
  17. data/lib/conjur/authn-api.rb +4 -0
  18. data/lib/conjur/authz-api.rb +4 -0
  19. data/lib/conjur/base.rb +31 -30
  20. data/lib/conjur/build_from_response.rb +11 -0
  21. data/lib/conjur/cast.rb +5 -1
  22. data/lib/conjur/core-api.rb +22 -2
  23. data/lib/conjur/deputy.rb +19 -2
  24. data/lib/conjur/env.rb +18 -3
  25. data/lib/conjur/escape.rb +65 -4
  26. data/lib/conjur/event_source.rb +15 -2
  27. data/lib/conjur/graph.rb +103 -12
  28. data/lib/conjur/has_id.rb +13 -1
  29. data/lib/conjur/has_identifier.rb +9 -6
  30. data/lib/conjur/has_owner.rb +21 -7
  31. data/lib/conjur/host.rb +8 -0
  32. data/lib/conjur/layer-api.rb +4 -0
  33. data/lib/conjur/layer.rb +50 -3
  34. data/lib/conjur/log.rb +22 -2
  35. data/lib/conjur/log_source.rb +27 -0
  36. data/lib/conjur/path_based.rb +47 -2
  37. data/lib/conjur/pubkeys-api.rb +12 -0
  38. data/lib/conjur/role.rb +220 -9
  39. data/lib/conjur/role_grant.rb +50 -2
  40. data/lib/conjur/secret.rb +9 -1
  41. data/lib/conjur/standard_methods.rb +31 -3
  42. data/lib/conjur/user.rb +55 -3
  43. data/spec/lib/role_spec.rb +1 -2
  44. metadata +2 -2
@@ -19,7 +19,18 @@
19
19
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  #
21
21
  module Conjur
22
+ # @api private
23
+ # This module is included by classes that can be built from JSON responses.
22
24
  module BuildFromResponse
25
+ # @api private
26
+ #
27
+ # Build a Conjur asset from a REST response.
28
+ #
29
+ # @param [RestCliet::Response] response the response to build the object from
30
+ # @param [Hash] credentials options as {Conjur::API#credentials} used to perform requests in methods on
31
+ # the created asset.
32
+ #
33
+ # @return [Object] an object of this type
23
34
  def build_from_response(response, credentials)
24
35
  new(response.headers[:location], credentials).tap do |obj|
25
36
  obj.attributes = JSON.parse(response.body)
data/lib/conjur/cast.rb CHANGED
@@ -21,7 +21,11 @@
21
21
  module Conjur
22
22
  module Cast
23
23
  protected
24
-
24
+
25
+ # Convert a value to a role or resource identifier.
26
+ #
27
+ # @param [String, Array, #roleid, #resourceid] obj the value to cast
28
+ # @param [Symbol] kind must be either `:roleid` or `:resourceid`
25
29
  def cast(obj, kind)
26
30
  case kind
27
31
  when :roleid, :resourceid
@@ -21,6 +21,11 @@
21
21
  module Conjur
22
22
  class API
23
23
  class << self
24
+ # @api private
25
+ #
26
+ # Host for the core service. We don't really use this anymore.
27
+ #
28
+ # @return [String] the core asset host
24
29
  def core_asset_host
25
30
  ::Conjur::Core::API.host
26
31
  end
@@ -30,14 +35,29 @@ module Conjur
30
35
  module Core
31
36
  class API < Conjur::API
32
37
  class << self
38
+ # @api private
39
+ # @deprecated
40
+ # The host for the Conjur directory service
41
+ # @return [String] the host.
33
42
  def host
34
43
  Conjur.configuration.core_url
35
44
  end
36
-
45
+
46
+ # Returns the account as determined by the conjur server.
47
+ #
48
+ # You should generally provide the account with {Conjur::Configuration#account}, but this method
49
+ # can determine it by asking the server.
50
+ #
51
+ # You do not need any credentials to call this method.
37
52
  def conjur_account
38
53
  info['account'] or raise "No account field in #{info.inspect}"
39
54
  end
40
-
55
+
56
+ # @api private
57
+ #
58
+ # Used to fetch an `info` hash from the server.
59
+ #
60
+ # @return [Hash] a hash containing an `'account'` field that specifies the current Conjur account.
41
61
  def info
42
62
  @info ||= JSON.parse RestClient::Resource.new(Conjur::Core::API.host)['info'].get
43
63
  end
data/lib/conjur/deputy.rb CHANGED
@@ -19,6 +19,14 @@
19
19
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  #
21
21
  module Conjur
22
+ # A Deputy is an actor, typically representing a service. It is given a login and
23
+ # an api key, just like {Conjur::Host}s and {Conjur::User}s, and can perform various
24
+ # actions.
25
+ #
26
+ # You should not create instances of this class directly. Instead, you can get a {Conjur::Deputy}
27
+ # instance with {Conjur::API#deputy} or {Conjur::API#create_deputy}.
28
+ #
29
+ # The deputies api is stable, but is primarily used internally.
22
30
  class Deputy < RestClient::Resource
23
31
  include Exists
24
32
  include HasId
@@ -26,11 +34,20 @@ module Conjur
26
34
  include HasAttributes
27
35
  include ActsAsUser
28
36
  include ActsAsResource
29
-
37
+
38
+ # Login for the deputy. Of the form "deputy/<deputy-id>".
39
+ #
40
+ # @return [String] the login.
30
41
  def login
31
42
  [ self.class.name.split('::')[-1].downcase, id ].join('/')
32
43
  end
33
-
44
+
45
+ # API Key that can be used to login as the deputy.
46
+ #
47
+ # This is only available if the {Conjur::Deputy} was returned
48
+ # by {Conjur::API#create_deputy}.
49
+ #
50
+ # @return [String] the api key.
34
51
  def api_key
35
52
  self.attributes['api_key']
36
53
  end
data/lib/conjur/env.rb CHANGED
@@ -21,18 +21,33 @@
21
21
  module Conjur
22
22
  extend self
23
23
 
24
+ # @deprecated
25
+ # @api private
26
+ # This method delegates to {Conjur::Configuration#service_base_port}
27
+ #
28
+ # @return [Integer] the service base port
24
29
  def service_base_port
25
30
  Conjur.configuration.service_base_port
26
31
  end
27
-
32
+
33
+ # This method delegates to {Conjur::Configuration#account}
34
+ #
35
+ # @return [String] the value of `Conjur.configuration.account`
28
36
  def account
29
37
  Conjur.configuration.account
30
38
  end
31
-
39
+
40
+ # This method delegates to {Conjur::Configuration#env}
41
+ # @return [String] the value of `Conjur.configuration.env`
32
42
  def env
33
43
  Conjur.configuration.env
34
44
  end
35
-
45
+
46
+ # @api private
47
+ # @deprecated
48
+ # This method delegates to {Conjur::Configuration#stack}
49
+ #
50
+ # @return [String] the value of `Conjur.configuration.stack`
36
51
  def stack
37
52
  Conjur.configuration.stack
38
53
  end
data/lib/conjur/escape.rb CHANGED
@@ -19,21 +19,56 @@
19
19
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  #
21
21
  module Conjur
22
+
23
+ # Provides helpers for escaping url components.
24
+ #
25
+ # The helpers are added as both class and isntance methods.
22
26
  module Escape
23
27
  module ClassMethods
28
+ # URL escape the entire string. This is essentially the same as calling `CGI.escape str`.
29
+ #
30
+ # @example
31
+ # fully_escape 'foo/bar@baz'
32
+ # # => "foo%2Fbar%40baz"
33
+ #
34
+ # @param [String] str the string to escape
35
+ # @return [String] the escaped string
24
36
  def fully_escape(str)
25
37
  require 'cgi'
26
38
  CGI.escape(str.to_s)
27
39
  end
28
-
40
+
41
+ # Escape a URI path component.
42
+ #
43
+ # This method simply calls {Conjur::Escape::ClassMethods#path_or_query_escape}.
44
+ #
45
+ # @param [String] str the string to escape
46
+ # @return [String] the escaped string
47
+ # @see Conjur::Escape::ClassMethods#path_or_query_escape
29
48
  def path_escape(str)
30
49
  path_or_query_escape str
31
50
  end
32
51
 
52
+ # Escape a URI query value.
53
+ #
54
+ # This method simply calls {Conjur::Escape::ClassMethods#path_or_query_escape}.
55
+ #
56
+ # @param [String] str the string to escape
57
+ # @return [String] the escaped string
58
+ # @see Conjur::Escape::ClassMethods#path_or_query_escape
33
59
  def query_escape(str)
34
60
  path_or_query_escape str
35
61
  end
36
-
62
+
63
+ # Escape a path or query value.
64
+ #
65
+ # This method is *similar* to `URI.escape`, but it has several important differences:
66
+ # * If a falsey value is given, the string `"false"` is returned.
67
+ # * If the value given responds to `#id`, the value returned by `str.id` is escaped instead.
68
+ # * The value is escaped without modifying `':'` or `'/'`.
69
+ #
70
+ # @param [String, FalseClass, NilClass, #id] str the value to escape
71
+ # @return [String] the value escaped as described
37
72
  def path_or_query_escape(str)
38
73
  return "false" unless str
39
74
  str = str.id if str.respond_to?(:id)
@@ -43,19 +78,45 @@ module Conjur
43
78
  URI.escape(str.to_s, Regexp.new("[^#{pattern}]"))
44
79
  end
45
80
  end
46
-
81
+
82
+ # @api private
83
+ # :nodoc:
47
84
  def self.included(base)
48
85
  base.extend ClassMethods
49
86
  end
50
-
87
+
88
+ # URL escape the entire string. This is essentially the same as calling `CGI.escape str`.
89
+ #
90
+ # @example
91
+ # fully_escape 'foo/bar@baz'
92
+ # # => "foo%2Fbar%40baz"
93
+ #
94
+ # @param [String] str the string to escape
95
+ # @return [String] the escaped string
96
+ # @see Conjur::Escape::ClassMethods#fully_escape
51
97
  def fully_escape(str)
52
98
  self.class.fully_escape str
53
99
  end
54
100
 
101
+ # Escape a URI path component.
102
+ #
103
+ # This method simply calls {Conjur::Escape::ClassMethods#path_or_query_escape}.
104
+ #
105
+ # @param [String] str the string to escape
106
+ # @return [String] the escaped string
107
+ # @see Conjur::Escape::ClassMethods#path_or_query_escape
55
108
  def path_escape(str)
56
109
  self.class.path_escape str
57
110
  end
58
111
 
112
+
113
+ # Escape a URI query value.
114
+ #
115
+ # This method simply calls {Conjur::Escape::ClassMethods#path_or_query_escape}.
116
+ #
117
+ # @param [String] str the string to escape
118
+ # @return [String] the escaped string
119
+ # @see Conjur::Escape::ClassMethods#path_or_query_escape
59
120
  def query_escape(str)
60
121
  self.class.query_escape str
61
122
  end
@@ -1,7 +1,13 @@
1
1
  module Conjur
2
+ # @api private
2
3
  # An EventSource instance is used to parse a stream in the format given by
3
4
  # the Server Sent Events standard: http://www.whatwg.org/specs/web-apps/current-work/#server-sent-events
5
+ #
6
+ # This class is used internally by the audit methods in follow mode.
7
+ #
4
8
  class EventSource
9
+ # @api private
10
+ # Representation of a SSE event
5
11
  class Event < Struct.new(:data, :name, :id);
6
12
  end
7
13
 
@@ -20,6 +26,8 @@ module Conjur
20
26
  attr_accessor :json
21
27
  alias json? json
22
28
 
29
+ # @api private
30
+ # Create an EventSource
23
31
  def initialize
24
32
  @json = true
25
33
  @on = {}
@@ -27,9 +35,11 @@ module Conjur
27
35
  @buffer = ""
28
36
  end
29
37
 
30
- # Feed a chunk of data to the EventSource and dispatch any fully receieved
38
+ # @api private
39
+ # Feed a chunk of data to the EventSource and dispatch any fully received
31
40
  # events.
32
41
  # @param [String] chunk the data to parse
42
+ # @return [void]
33
43
  def feed chunk
34
44
  @buffer << chunk
35
45
 
@@ -38,7 +48,10 @@ module Conjur
38
48
  end
39
49
  end
40
50
 
41
- # Adds a listener for :name:
51
+ # Add a block to be called when events with an `'event'` field of `name` are received.
52
+ #
53
+ # @param [String, Symbol] name the name to listen for
54
+ # @yieldparam [Conjur::EventSource::Event] the event
42
55
  def on name, &block
43
56
  (@on[name.to_sym] ||= []) << block
44
57
  end
data/lib/conjur/graph.rb CHANGED
@@ -19,15 +19,30 @@
19
19
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  #
21
21
  module Conjur
22
+
23
+ # A Graph represents a directed graph of roles.
24
+ #
25
+ # An instance of this class is returned by {Conjur::API#role_graph}.
26
+ #
27
+ # @example Graphs act like arrays of edges
28
+ # graph.each do |edge|
29
+ # puts "#{edge.parent} -> #{edge.child}"
30
+ # end
31
+ # # role1 -> role2
32
+ # # role2 -> role3
33
+ #
22
34
  class Graph
23
35
 
24
36
  include Enumerable
25
37
 
26
- # @!attribute r edges
27
- # @return [Array<Conjur::Graph::Edge>] the edges of this graph
38
+ # Returns an array containing the directed edges of the graph.
39
+ #
40
+ # @return [Array<Conjur::Graph::Edge>] the edges of this graph
28
41
  attr_reader :edges
29
42
 
30
43
  # @api private
44
+ #
45
+ # @param val [String, Hash, Array, Graph] Data from which to initialize the instance
31
46
  def initialize val
32
47
  @edges = case val
33
48
  when String then JSON.parse(val)['graph']
@@ -41,8 +56,9 @@ module Conjur
41
56
  end
42
57
 
43
58
  # Enumerates the edges of this graph.
44
- # @yieldparam [Conjur::Graph::Edge] each edge of the graph
45
- # @return edge [Conjur::Graph] this graph
59
+ #
60
+ # @yieldparam [Conjur::Graph::Edge] edge each edge of the graph
61
+ # @return [Conjur::Graph] this graph
46
62
  def each_edge
47
63
  return enum_for(__method__) unless block_given?
48
64
  edges.each{|e| yield e}
@@ -52,28 +68,59 @@ module Conjur
52
68
  alias each each_edge
53
69
 
54
70
  # Enumerates the vertices (roles) of this graph
55
- # @yieldparam vertex [Conjur::Role] each vertex in this graph
71
+ # @yieldparam [Conjur::Role] vertex each vertex in this graph
56
72
  # @return [Conjur::Graph] this graph
57
73
  def each_vertex
58
74
  return enum_for(__method__) unless block_given?
59
75
  vertices.each{|v| yield v}
60
76
  end
61
77
 
62
-
78
+ # Serialize the graph as JSON
79
+ # @param [Boolean] short when true, the graph is serialized as an array of arrays instead of an array of hashes.
80
+ # @return [String] the JSON serialized graph.
81
+ # @see #as_json
82
+ #
63
83
  def to_json short = false
64
84
  as_json(short).to_json
65
85
  end
66
86
 
87
+ # Convert the graph to a JSON serializable data structure. The value returned by this method can have two
88
+ # forms: An array of arrays when `short` is `true`, or hash like
89
+ # `{ 'graph' => [ {'parent' => 'roleid', 'child' => 'roleid'} ]}` otherwise.
90
+ #
91
+ # @example Graph formats
92
+ # graph = api.role_graph 'conjur:group:pubkeys-1.0/key-managers'
93
+ #
94
+ # # Short format
95
+ # graph.as_json true
96
+ # # => [
97
+ # # ["conjur:group:pubkeys-1.0/key-managers", "conjur:group:pubkeys-1.0/admin"],
98
+ # # ["conjur:group:pubkeys-1.0/admin", "conjur:user:admin"]
99
+ # # ]
100
+ #
101
+ # # Default format (you can omit the false parameter in this case)
102
+ # graph.as_json false
103
+ # # => {
104
+ # # "graph" => [
105
+ # # {"parent"=>"conjur:group:pubkeys-1.0/key-managers", "child"=>"conjur:group:pubkeys-1.0/admin"},
106
+ # # {"parent"=>"conjur:group:pubkeys-1.0/admin", "child"=>"conjur:user:admin"}
107
+ # # ]
108
+ # #}
109
+ #
110
+ # @param [Boolean] short whether to use short of default format
111
+ # @return [Hash, Array] JSON serializable representation of the graph
67
112
  def as_json short = false
68
113
  edges = self.edges.map{|e| e.as_json(short)}
69
114
  short ? edges : {'graph' => edges}
70
115
  end
71
116
 
72
- # @param [String, NilClass] name to assign to the graph. Usually this can be omitted unless you
73
- # are writing multiple graphs to a single file. Must be in the ID format specified by
74
- # http://www.graphviz.org/content/dot-language
117
+ # Returns a string formatted for use by the {http://www.graphviz.org/ graphviz dot} tool.
118
+ #
119
+ # @param [String, NilClass] name An identifier to assign to the graph. This can be omitted unless you
120
+ # are writing multiple graphs to a single file. This must be in the ID format specified by
121
+ # http://www.graphviz.org/content/dot-language.
75
122
  #
76
- # @return [String] the dot format (used by graphvis, among others) representation of this graph.
123
+ # @return [String] the dot format (used by graphviz, among others) representation of this graph.
77
124
  def to_dot name = nil
78
125
  dot = "digraph #{name || ''} {"
79
126
  vertices.each do |v|
@@ -84,7 +131,9 @@ module Conjur
84
131
  end
85
132
  dot << "\n}"
86
133
  end
87
-
134
+
135
+ # Return the vertices (roles) of the graph as an array.
136
+ # @return [Array<Conjur::Role>] the vertices/roles
88
137
  def vertices
89
138
  @vertices ||= edges.inject([]) {|a, pair| a.concat pair.to_a }.uniq
90
139
  end
@@ -148,41 +197,83 @@ module Conjur
148
197
  "#{parent_id} -> #{child_id}"
149
198
  end
150
199
 
151
- # an edge consisting of a parent & child, both of which are Conjur::Role instances
200
+ # Represents a directed Edge between a parent role and a child role.
201
+ #
202
+ # In this context, the parent role is a *member of* the child role. For example,
203
+ # the `admin` role is a parent of every role, either directly or indirectly, because
204
+ # it is added as a member to all roles it creates.
152
205
  class Edge
206
+
207
+ # Return the parent of this edge. The {#parent} role *is a member of* the {#child} role.
208
+ # @return [Conjur::Role] the parent role
153
209
  attr_reader :parent
210
+
211
+ # Return the child of this edge. The {#parent} role *is a member of* the {#child} role.
212
+ # @return [Conjur::Role] the child role
154
213
  attr_reader :child
155
214
 
215
+ # Create a directed edge with a parent and child
216
+ #
217
+ # @param [Conjur::Role] parent the parent or source of this edge
218
+ # @param [Conjur::Role] child the child or destination of this edge
156
219
  def initialize parent, child
157
220
  @parent = parent
158
221
  @child = child
159
222
  end
160
223
 
224
+ # Serialize this edge as JSON.
225
+ #
226
+ # @see #as_json
227
+ # @param [Boolean] short when true, serialize the edge as an Array instead of a Hash
228
+ # @return [String] the JSON serialized edge
161
229
  def to_json short = false
162
230
  as_json(short).to_json
163
231
  end
164
232
 
233
+ # Return a value suitable for JSON serialization.
234
+ #
235
+ # The `short` parameter determines whether to return a `["parent", "child"]` Array
236
+ # or a Hash like `{"parent" => "parent-role", "child" => "child-role"}`.
237
+ #
238
+ # @param [Boolean] short return an Array when true, otherwise return a Hash.
239
+ # @return [Array, Hash] value suitable for JSON serialization
165
240
  def as_json short = false
166
241
  short ? to_a : to_h
167
242
  end
168
243
 
244
+ # Return this edge as a Hash like {"parent" => "...", "child" => "..."}.
245
+ #
246
+ # Note that the keys in the hash are strings.
247
+ #
248
+ # @return [Hash] a Hash representing this edge
169
249
  def to_h
170
250
  # return string keys to make testing less brittle
171
251
  {'parent' => @parent, 'child' => @child}
172
252
  end
173
253
 
254
+ # Return this edge as an Array like ["parent", "child"]
255
+ #
256
+ # @return [Array<String>] the edge as an Array
174
257
  def to_a
175
258
  [@parent, @child]
176
259
  end
177
260
 
261
+ # @api private
262
+ # :nodoc:
178
263
  def to_s
179
264
  "<Edge #{parent.id} --> #{child.id}>"
180
265
  end
181
266
 
267
+ # Support using edges as hash keys
268
+ # @api private
269
+ # :nodoc:
182
270
  def hash
183
271
  @hash ||= to_a.map(&:to_s).hash
184
272
  end
185
273
 
274
+ # Support using edges as hash keys and equality testing
275
+ # @api private
276
+ # :nodoc:
186
277
  def == other
187
278
  other.kind_of?(self.class) and other.parent == parent and other.child == child
188
279
  end