conjur-api 4.13.0 → 4.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/CHANGELOG.md +8 -0
  4. data/Gemfile +0 -1
  5. data/README.md +59 -18
  6. data/conjur-api.gemspec +2 -1
  7. data/lib/conjur/acts_as_asset.rb +6 -9
  8. data/lib/conjur/acts_as_role.rb +54 -7
  9. data/lib/conjur/annotations.rb +52 -14
  10. data/lib/conjur/api/audit.rb +54 -8
  11. data/lib/conjur/api/authn.rb +54 -9
  12. data/lib/conjur/api/groups.rb +67 -4
  13. data/lib/conjur/api/hosts.rb +62 -3
  14. data/lib/conjur/api/layers.rb +48 -3
  15. data/lib/conjur/api/pubkeys.rb +140 -9
  16. data/lib/conjur/api.rb +13 -1
  17. data/lib/conjur/base.rb +93 -6
  18. data/lib/conjur/configuration.rb +247 -20
  19. data/lib/conjur/exists.rb +26 -0
  20. data/lib/conjur/group.rb +50 -4
  21. data/lib/conjur/has_attributes.rb +66 -5
  22. data/lib/conjur/resource.rb +155 -13
  23. data/lib/conjur/role.rb +1 -1
  24. data/lib/conjur/standard_methods.rb +7 -2
  25. data/lib/conjur/variable.rb +168 -6
  26. data/lib/conjur-api/version.rb +1 -1
  27. data/lib/conjur-api.rb +2 -0
  28. data/spec/api/authn_spec.rb +6 -3
  29. data/spec/api/groups_spec.rb +1 -1
  30. data/spec/api/pubkeys_spec.rb +4 -4
  31. data/spec/api/roles_spec.rb +4 -2
  32. data/spec/api/users_spec.rb +2 -2
  33. data/spec/api/variables_spec.rb +1 -1
  34. data/spec/helpers/errors_matcher.rb +34 -0
  35. data/spec/helpers/request_helpers.rb +10 -0
  36. data/spec/lib/annotations_spec.rb +5 -2
  37. data/spec/lib/audit_spec.rb +5 -5
  38. data/spec/lib/group_spec.rb +1 -1
  39. data/spec/lib/resource_spec.rb +11 -11
  40. data/spec/lib/role_spec.rb +8 -7
  41. data/spec/lib/user_spec.rb +7 -3
  42. data/spec/ssl_spec.rb +85 -0
  43. data/spec/standard_methods_helper.rb +2 -0
  44. data/spec/variable_spec.rb +5 -3
  45. metadata +34 -7
  46. data/lib/conjur/patches/rest-client.rb +0 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 30c179935696f866037eeb767bc75a37fa852d2f
4
- data.tar.gz: dbb483606b3f77c0340e4fd46c97ac954cb72920
3
+ metadata.gz: fa094471717dc9bb39477d76468d2663895d9fd4
4
+ data.tar.gz: d688adf16203e25c50646994bc619170d5633b89
5
5
  SHA512:
6
- metadata.gz: 3b328c7fc9790246d738f07f9983c787d5024643fd41655430992d4526fd07106ddaae791572c4581a6f222b2bff370e6954125de91fa6f56382f7d93d93eed1
7
- data.tar.gz: d754a280ea0ad20a031d1b0561ca1338bc08bcff3df5d99b4992e605106c18b2c02b66d5207e3fe108d5b76fba7ed91e3096f04a74e6d2c002a9ec97482504aa
6
+ metadata.gz: 434da500b0bb392deb9f0e8380dab357394aa2b16f28bb5063f2619a484646c1a1912267ee48eed7e3cea4d9e88ac256e23c466f6bd25faf1123294cce68af58
7
+ data.tar.gz: d9097541c2faff292c2f2c201a5b2d7dac162ca4c023b45d52093215acb310a17ce295762dc221d3a7c2952554c0efff59b911518853eea4282feca61648e330
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --hide-void-return --markup markdown --no-private --hide-api private lib/**/*.rb
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ # v4.14.0
2
+
3
+ * Bump rest-client version, remove the troublesome mime-types patch
4
+ * Make sure SSL certificate verification is enabled
5
+ * Bugfix: Don't escape ids twice when listing records
6
+ * Add a stub so that require 'conjur-api' works
7
+ * Lots of doc updates
8
+
1
9
  # v4.13.0
2
10
 
3
11
  * Add GID handling utilities
data/Gemfile CHANGED
@@ -8,4 +8,3 @@ gemspec
8
8
  group :development do
9
9
  gem 'pry'
10
10
  end
11
-
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Programmatic Ruby access to the Conjur API.
4
4
 
5
- ## Installation
5
+ # Installation
6
6
 
7
7
  Add this line to your application's Gemfile:
8
8
 
@@ -16,44 +16,85 @@ Or install it yourself as:
16
16
 
17
17
  $ gem install conjur-api
18
18
 
19
- ## Usage
19
+ # Usage
20
20
 
21
- ### Programmatic configuration
21
+ Connecting to Conjur is a two-step process:
22
22
 
23
- To configure the API to connect to Conjur, specify the account and appliance_url (both of which are required) like this:
23
+ * **Configuration** Instruct the API where to find the Conjur endpoint and how to secure the connection.
24
+ * **Authentication** Provide the API with credentials that it can use to authenticate.
25
+
26
+ ## Configuration
27
+
28
+ The simplest way to configure the Conjur API is to use the configuration file stored on the machine.
29
+ If you have configured the machine with [conjur init](http://developer.conjur.net/reference/tools/init.html),
30
+ it's default location is `~/.conjurrc`.
31
+
32
+ The Conjur configuration process also checks `/etc/conjur.conf` for global settings. This is typically used
33
+ in server environments.
34
+
35
+ For custom scenarios, the location of the file can be overridden using the `CONJURRC` environment variable.
36
+
37
+ You can load the Conjur configuration file using the following Ruby code:
24
38
 
25
39
  ```ruby
26
- Conjur.configuration.account = 'my-account'
27
- Conjur.configuration.appliance_url = 'https://conjur.mydomain.com/api'
40
+ require 'conjur/cli'
41
+ Conjur::Config.load
42
+ Conjur::Config.apply
28
43
  ```
29
44
 
30
- You can also specify these values in environment variables, which is often a bit more convenient. Environment variables are mapped to configuration variables by prepending CONJUR_ to the all-caps name of the configuration variable, for example, `appliance_url` is `CONJUR_APPLIANCE_URL`, `account` is `CONJUR_ACCOUNT`, etc.
45
+ **Note** this code requires the [conjur-cli](https://github.com/conjurinc/cli-ruby) gem, which should also be in your
46
+ gemset or bundle.
31
47
 
32
- In either case, if you are using Conjur's self-signed cert, you will also need to configure certificate trust:
48
+ ## Authentication
49
+
50
+ Once Conjur is configured, the connection can be established like this:
33
51
 
34
52
  ```ruby
35
- OpenSSL::SSL::SSLContext::DEFAULT_CERT_STORE.add_file "/path/to/conjur-youraccount.pem"
53
+ conjur = Conjur::Authn.connect nil, noask: true
36
54
  ```
37
55
 
38
- ### Using Conjur system configuraiton
56
+ To [authenticate](http://developer.conjur.net/reference/services/authentication/authenticate.html), the API client must
57
+ provide a `login` name and `api_key`. The `Conjur::Authn.connect` will attempt the following, in order:
58
+
59
+ 1. Look for `login` in environment variable `CONJUR_AUTHN_LOGIN`, and `api_key` in `CONJUR_AUTHN_API_KEY`
60
+ 2. Look for credentials on disk. The default credentials file is `~/.netrc`. The location of the credentials file
61
+ can be overridden using the configuration file `netrc_path` option.
62
+ 3. Prompt for credentials. This can be disabled using the option `noask: true`.
63
+
64
+ ## Connecting Without Files
39
65
 
40
- To instantiate the API using configuration stored stored in `/etc/conjur.conf` and/or `~/.conjurrc`:
66
+ It's possible to configure and authenticate the Conjur connection without using any files, and without requiring
67
+ the `conjur-cli` gem.
68
+
69
+ To accomplish this, apply the configuration settings directly to the [Conjur::Configuration](https://github.com/conjurinc/api-ruby/blob/master/lib/conjur/configuration.rb)
70
+ object.
71
+
72
+ For example, specify the `account` and `appliance_url` (both of which are required) like this:
41
73
 
42
74
  ```ruby
43
- require 'conjur/cli'
44
- Conjur::Config.load
45
- Conjur::Config.apply
46
- conjur = Conjur::API.new_from_key username, api_key
75
+ Conjur.configuration.account = 'my-account'
76
+ Conjur.configuration.appliance_url = 'https://conjur.mydomain.com/api'
47
77
  ```
48
78
 
49
- `username` and `api_key` can also be provided by environment variables: `CONJUR_AUTHN_LOGIN` and `CONJUR_AUTHN_API_KEY`. If the login is a host, the `CONJUR_AUTHN_LOGIN` should be prefixed with `host/`. For example: `host/myhost.example.com`.
79
+ You can also specify these values using environment variables, which is often a bit more convenient.
80
+ Environment variables are mapped to configuration variables by prepending `CONJUR_` to the all-caps name of the
81
+ configuration variable. For example, `appliance_url` is `CONJUR_APPLIANCE_URL`, `account` is `CONJUR_ACCOUNT`.
82
+
83
+ In either case, you will also need to configure certificate trust. For example:
84
+
85
+ ```ruby
86
+ OpenSSL::SSL::SSLContext::DEFAULT_CERT_STORE.add_file "/etc/conjur-yourorg.pem"
87
+ ```
50
88
 
51
- If the login and API key are provided by `netrc` or by the environment, you can construct an API client using:
89
+ Once Conjur is configured, you can create a new API client by providing a `login` and `api_key`:
52
90
 
53
91
  ```ruby
54
- conjur = Conjur::Authn.connect
92
+ Conjur::API.new_from_key login, api_key
55
93
  ```
56
94
 
95
+ Note that if you are connecting as a [Host](http://developer.conjur.net/reference/services/directory/host), the login should be
96
+ prefixed with `host/`. For example: `host/myhost.example.com`, not just `myhost.example.com`.
97
+
57
98
  ## Contributing
58
99
 
59
100
  1. Fork it
data/conjur-api.gemspec CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |gem|
19
19
  gem.required_ruby_version = '>= 1.9'
20
20
 
21
21
 
22
- gem.add_dependency 'rest-client', '= 1.6.7' # with newer versions adding certificates to OpenSSL does not work
22
+ gem.add_dependency 'rest-client', '~> 1.7', '>= 1.7.3'
23
23
  gem.add_dependency 'activesupport'
24
24
 
25
25
  gem.add_development_dependency 'rake'
@@ -33,4 +33,5 @@ Gem::Specification.new do |gem|
33
33
  gem.add_development_dependency 'yard'
34
34
  gem.add_development_dependency 'redcarpet'
35
35
  gem.add_development_dependency 'timecop'
36
+ gem.add_development_dependency 'inch'
36
37
  end
@@ -20,15 +20,12 @@
20
20
  #
21
21
  module Conjur
22
22
  module ActsAsAsset
23
- def self.included(base)
24
- base.instance_eval do
25
- include HasId
26
- include Exists
27
- include HasOwner
28
- include ActsAsResource
29
- include HasAttributes
30
- end
31
- end
23
+ include HasId
24
+ include Exists
25
+ include HasOwner
26
+ include ActsAsResource
27
+ include HasAttributes
28
+
32
29
 
33
30
  def add_member(role_name, member, options = {})
34
31
  owned_role(role_name).grant_to member, options
@@ -19,29 +19,76 @@
19
19
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  #
21
21
  module Conjur
22
+
23
+ # This module provides methods for things that have an associated {Conjur::Role}.
24
+ #
25
+ # All high level Conjur assets (groups and users, for example) are composed of both a role and a resource. This allows
26
+ # these assets to have permissions on other assets, and for other assets to have permission
27
+ # on them.
28
+ #
29
+ # The {Conjur::ActsAsRole} module itself should be considered private, but it's methods are
30
+ # public when added to a Conjur asset class.
22
31
  module ActsAsRole
32
+
33
+ # The qualified identifier for the role associated with this asset. A *qualified* identifier
34
+ # prepends the asset's account and kind, for example, a {Conjur::User} with login `'bob'` in a
35
+ # system with organizational account `'conjur'` would have a `roleid` of `'conjur:user:bob'`
36
+ #
37
+ # @return [String] the qualified role id
23
38
  def roleid
24
39
  [ core_conjur_account, role_kind, id ].join(':')
25
40
  end
26
-
41
+ alias role_id roleid
42
+
43
+ # The `kind` of a role. This may be any value, but standard ones correspond to various high level
44
+ # Conjur assets, for example, `'user'`, `'group'`, or `'variable'`.
45
+ #
46
+ # Note that this method derives the role kind from the asset's class name.
47
+ #
48
+ # @return [String] the role kind
27
49
  def role_kind
28
50
  self.class.name.split('::')[-1].underscore
29
51
  end
30
-
31
- # NOTE: parse_role_id returns tuple of path components
32
- # (basically, same components as in 'roleid' plus some prefixes)
52
+
53
+ # Get a {Conjur::Role} instance corresponding to the `role` associated with this asset.
33
54
  def role
34
55
  require 'conjur/role'
35
56
  Conjur::Role.new(Conjur::Authz::API.host, self.options)[Conjur::API.parse_role_id(self.roleid).join('/')]
36
57
  end
37
-
38
- # Permit this role to perform a privileged action.
58
+
59
+ # Permit the asset to perform `privilege` on `resource`. You can also use this method to control whether the role
60
+ # is able to grant the privilege on the resource to other roles by passing a `:grant_option` option.
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.
66
+ #
67
+ # ### Permissions
68
+ #
69
+ # To call this method, you must *own* the resource, or have the privilege on it with grant option set to true.
70
+ #
71
+ # @api dsl
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]
39
77
  def can(privilege, resource, options = {})
40
78
  require 'conjur/resource'
41
79
  Conjur::Resource.new(Conjur::Authz::API.host, self.options)[Conjur::API.parse_resource_id(resource).join('/')].permit privilege, self.roleid, options
42
80
  end
43
81
 
44
- # Deny this role from performing perform a privileged action.
82
+ # Deny the asset's role the ability to perform `privilege` on `resource`. This operation is the inverse of {#can}.
83
+ #
84
+ # This method is primarily intended for use in the
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.
88
+ #
89
+ # @see Conjur::Resource#deny
90
+ #
91
+ # @api dsl
45
92
  def cannot(privilege, resource, options = {})
46
93
  require 'conjur/resource'
47
94
  Conjur::Resource.new(Conjur::Authz::API.host, self.options)[Conjur::API.parse_resource_id(resource).join('/')].deny privilege, self.roleid
@@ -19,13 +19,26 @@
19
19
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  #
21
21
  module Conjur
22
+ # Conjur allows {http://developer.conjur.net/reference/services/authorization/resource Resource}
23
+ # instances to be {http://developer.conjur.net/reference/services/authorization/resource/annotate.html annotated}
24
+ # with arbitrary key-value data. This data is generally for "user consumption", and it *is not* governed
25
+ # by any particular schema or constraints. Your applications can define their own schema for annotations they
26
+ # use. If you do so, we recommend prefixing your annotations, for example, `'myapp:Name'`, in order to avoid
27
+ # conflict with annotations used, for example, by the Conjur UI.
28
+ #
22
29
  # An Annotations instance acts like a Hash: you can fetch an annotation
23
- # with '[]' and update with '[]=', 'each' it, and 'merge!' to do bulk updates
24
- # (although merge! is not more efficient than setting each pair with '[]=').
30
+ # with {#[]} and update with {#[]=}, {#each} it, and {#merge!} to do bulk updates.
31
+ #
25
32
  class Annotations
26
33
  include Enumerable
27
-
28
- # @api private
34
+
35
+ # Create an `Annotations` instance for the given {Conjur::Resource}.
36
+ #
37
+ # Note that you will generally use the {Conjur::Resource#annotations} method to get
38
+ # the `Annotations` for a {Conjur::Resource}.
39
+ #
40
+ # @param resource [Conjur::Resource]
41
+ #
29
42
  def initialize resource
30
43
  @resource = resource
31
44
  end
@@ -37,11 +50,15 @@ module Conjur
37
50
  annotations_hash[name.to_sym]
38
51
  end
39
52
 
40
- # Set an annotation value
53
+ # Set an annotation value. This will perform an api call to set the annotation
54
+ # on the server.
55
+ #
41
56
  # @param [String, Symbol] name the annotation name
42
57
  # @param [String] value the annotation value
58
+ #
59
+ # @return [String] the new annotation value
43
60
  def []= name, value
44
- update_annotation name, value
61
+ update_annotation name.to_sym, value
45
62
  value
46
63
  end
47
64
 
@@ -52,31 +69,48 @@ module Conjur
52
69
  self
53
70
  end
54
71
 
55
- # Set annotations from key,value pairs in +hash+
56
- # @param [#each] hash
72
+ # Set annotations from key,value pairs in `hash`.
73
+ #
74
+ # @note this is currently no more efficient than setting each
75
+ # annotation with {#[]=}.
76
+ #
77
+ # @param [Hash, #each] hash
57
78
  # @return [Conjur::Annotations] self
58
79
  def merge! hash
59
80
  hash.each{|k,v| self[k] = v }
60
81
  self
61
82
  end
62
83
 
63
- # Return a proper hash containing a +copy+ of ourself. Note that
84
+ # Return a proper hash containing a **copy** of the annotations. Note that
64
85
  # updates to this hash have no effect on the actual annotations.
86
+ #
65
87
  # @return [Hash]
66
88
  def to_h
67
89
  annotations_hash.dup
68
90
  end
69
-
91
+
92
+ # Return the annotations hash as a string. This method simply delegates to
93
+ # `Hash#to_s`.
94
+ #
95
+ # @return [String]
70
96
  def to_s
71
97
  annotations_hash.to_s
72
98
  end
73
-
99
+
100
+ # Return an informative representation of the annotations, including
101
+ # the resource to which they're attached. Suitable for debugging.
102
+ #
103
+ # @return [String]
74
104
  def inspect
75
105
  "<Annotations for #{@resource.resourceid}: #{to_s}>"
76
106
  end
77
107
 
78
108
  protected
79
-
109
+ #@api private
110
+ # Update an annotation on the server.
111
+ # @param name [String]
112
+ # @param value [String, #to_s]
113
+ # @return [void]
80
114
  def update_annotation name, value
81
115
  @resource.invalidate do
82
116
  @annotations_hash = nil
@@ -84,11 +118,15 @@ module Conjur
84
118
  RestClient::Resource.new(Conjur::Authz::API.host, @resource.options)[path].put name: name, value: value
85
119
  end
86
120
  end
87
-
121
+
122
+ # @api private
123
+ # Our internal {Hash} of annotations. Lazily loaded.
88
124
  def annotations_hash
89
125
  @annotations_hash ||= fetch_annotations
90
126
  end
91
-
127
+
128
+ # @api private
129
+ # Fetch the annotations from the server.
92
130
  def fetch_annotations
93
131
  {}.tap do |hash|
94
132
  @resource.attributes['annotations'].each do |annotation|
@@ -20,24 +20,70 @@
20
20
 
21
21
  require 'conjur/event_source'
22
22
  module Conjur
23
+
24
+
23
25
  class API
24
- # Return all events visible to the current authorized role
26
+ #@!group Audit Service
27
+
28
+ # Return up to 100 audit events visible to the current authorized role.
29
+ #
30
+ # An audit event is visible to a role if that role or one of it's ancestors is in the
31
+ # event's `:roles` field, or the role has a privilege any of the event's `:resources` field.
32
+ #
33
+ # @param options [Hash]
34
+ # @option options [Time, nil] :till only show events before this time
35
+ # @option options [Time, nil] :since only show events after this time
36
+ # @option options [Boolean] :follow block the current thread and call `block` with `Array` of
37
+ # audit events as the occur.
38
+ #
39
+ # @see #audit_role
40
+ #
41
+ # @return [Array<Hash>] the audit events
25
42
  def audit options={}, &block
26
43
  audit_event_feed "", options, &block
27
44
  end
28
-
29
- # Return audit events related to the given role_id. Identitical to audit_events
30
- # except that a String may be given instead of a Role object.
31
- # @param role [String] the role for which events should be returned.
45
+
46
+ # Return up to 100 audit events visible to the current role and related to the given role.
47
+ #
48
+ # See {#audit} for the conditions under which an event is visible to a role.
49
+ #
50
+ # An event is said to be "related to" a role iff the role is a member of the event's
51
+ # `:roles` field.
52
+ #
53
+ # @param role [Conjur::Role, String, #roleid] the role to audit (if a string is given, it must
54
+ # be of the form `'account:kind:id'`).
55
+ # @param options [Hash]
56
+ # @option options [Time, nil] :till only show events before this time
57
+ # @option options [Time, nil] :since only show events after this time
58
+ # @option options [Boolean] :follow block the current thread and call `block` with `Array` of
59
+ # audit events as the occur.
60
+ #
61
+ # @return [Array<Hash>] the audit events
32
62
  def audit_role role, options={}, &block
33
63
  audit_event_feed "roles/#{CGI.escape cast(role, :roleid)}", options, &block
34
64
  end
35
-
36
- # Return audit events related to the given resource
65
+
66
+ # Return up to 100 audit events visible to the current role and related to the given resource.
67
+ #
68
+ # See {#audit} for the conditions under which an event is visible to a role.
69
+ #
70
+ # An event is said to be "related to" a role iff the role is a member of the event's
71
+ # `:roles` field.
72
+ # @param resource [Conjur::Resource, String, #resourceid] the resource to audit (when a string is given, it must be
73
+ # of the form `'account:kind:id'`).
74
+ # @param options [Hash]
75
+ # @option options [Time, nil] :till only show events before this time
76
+ # @option options [Time, nil] :since only show events after this time
77
+ # @option options [Boolean] :follow block the current thread and call `block` with `Array` of
78
+ # audit events as the occur.
79
+ #
80
+ # @return [Array<Hash>] the audit events
37
81
  def audit_resource resource, options={}, &block
38
82
  audit_event_feed "resources/#{CGI.escape cast(resource, :resourceid)}", options, &block
39
83
  end
40
-
84
+
85
+ #@!endgroup
86
+
41
87
  private
42
88
  def audit_event_feed path, options={}, &block
43
89
  query = options.slice(:since, :till)
@@ -23,7 +23,28 @@ require 'conjur/user'
23
23
  module Conjur
24
24
  class API
25
25
  class << self
26
- # Perform login by Basic authentication.
26
+ #@!group Authentication Methods
27
+
28
+ # The Conjur {http://developer.conjur.net/reference/services/authentication/login.html login}
29
+ # operation exchanges a username and a password for an api key. The api key
30
+ # is preferable for storage and use in code, as it can be rotated and has far greater entropy than
31
+ # a user memorizable password.
32
+ #
33
+ # * Note that this method works only for {http://developer.conjur.net/reference/services/directory/user Users}. While
34
+ # {http://developer.conjur.net/reference/services/directory/hosts Hosts} possess Conjur identities, they do not
35
+ # have passwords.
36
+ # * If you pass an api key to this method instead of a password, it will simply return the API key.
37
+ # * This method uses Basic Auth to send the credentials.
38
+ #
39
+ # @example
40
+ # bob_api_key = Conjur::API.login('bob', 'bob_password')
41
+ # bob_api_key == Conjur::API.login('bob', bob_api_key) # => true
42
+ #
43
+ # @param [String] username The `username` or `login` for the
44
+ # {http://developer.conjur.net/reference/services/directory/user Conjur User}.
45
+ # @param [String] password The `password` or `api key` to authenticate with.
46
+ # @return [String] the API key.
47
+ # @raise [RestClient::Exception] when the request fails or the identity provided is invalid.
27
48
  def login username, password
28
49
  if Conjur.log
29
50
  Conjur.log << "Logging in #{username} via Basic authentication\n"
@@ -31,7 +52,16 @@ module Conjur
31
52
  RestClient::Resource.new(Conjur::Authn::API.host, user: username, password: password)['users/login'].get
32
53
  end
33
54
 
34
- # Perform login by CAS authentication.
55
+ # TODO I have NO idea how to document login_cas!
56
+
57
+ # This method logs in via CAS. It is similar to the {.login} method, the only difference being that
58
+ # you need a `cas_api_url`, provided by the administrator of your `CAS` service.
59
+ #
60
+ # @see .login
61
+ # @param [String] username the Conjur username
62
+ # @param [String] password the Conjur password
63
+ # @param [String] cas_api_url the url of the CAS service
64
+ # @return [String] a `CAS` ticket
35
65
  def login_cas username, password, cas_api_url
36
66
  if Conjur.log
37
67
  Conjur.log << "Logging in #{username} via CAS authentication\n"
@@ -41,27 +71,42 @@ module Conjur
41
71
  client.get("#{Conjur::Authn::API.host}/users/login").body
42
72
  end
43
73
 
74
+ # The Conjur {http://developer.conjur.net/reference/services/authentication/authenticate.html authenticate} operation
75
+ # exchanges Conjur credentials for a token. The token can then be used to authenticate further API calls.
76
+ #
77
+ # You will generally not need to use this method, as the API manages tokens automatically for you.
78
+ #
79
+ # @param [String] username The username or host id for which we want a token
80
+ # @param [String] password The password or api key
81
+ # @return [String] A JSON formatted authentication token.
44
82
  def authenticate username, password
45
83
  if Conjur.log
46
84
  Conjur.log << "Authenticating #{username}\n"
47
85
  end
48
86
  JSON::parse(RestClient::Resource.new(Conjur::Authn::API.host)["users/#{fully_escape username}/authenticate"].post password, content_type: 'text/plain')
49
87
  end
50
-
88
+
89
+ # Change a user's password. To do this, you must have the user's current password. This does not change or rotate
90
+ # api keys. However, you *can* use the user's api key as the *current* password, if the user was not created
91
+ # with a password.
92
+ #
93
+ # @param [String] username the name of the user whose password we want to change
94
+ # @param [String] password the user's *current* password *or* api key
95
+ # @param [String] new_password the new password for the user.
96
+ # @return [void]
51
97
  def update_password username, password, new_password
52
98
  if Conjur.log
53
99
  Conjur.log << "Updating password for #{username}\n"
54
100
  end
55
101
  RestClient::Resource.new(Conjur::Authn::API.host, user: username, password: password)['users/password'].put new_password
56
102
  end
103
+
104
+ #@!endgroup
57
105
  end
58
106
 
59
- # Options:
60
- # +password+
61
- #
62
- # Response:
63
- # +login+
64
- # +api_key+
107
+ # @api private
108
+ # This is used internally to create a user that we can log in as without creating
109
+ # an actual user in the directory, as with #create_user.
65
110
  def create_authn_user login, options = {}
66
111
  log do |logger|
67
112
  logger << "Creating authn user #{login}"
@@ -20,29 +20,92 @@
20
20
  require 'conjur/group'
21
21
 
22
22
  module Conjur
23
+
24
+
23
25
  class API
26
+ # @!group Directory: Groups
27
+
28
+ # List all Conjur groups visible to the current role. This method does not
29
+ # support advanced query options. If you want those, use `#resources` with
30
+ # the `:kind` option set to `'group'`.
31
+ #
32
+ # @example
33
+ # api.groups.count # => 163 (yikes!)
34
+ #
35
+ # @param options [Hash] included for compatibility. Do not use this parameter!
36
+ # @return [Array<Conjur::Group>]
24
37
  def groups(options={})
25
38
  standard_list Conjur::Core::API.host, :group, options
26
39
  end
27
40
 
41
+ # Create a new group with the given identifier.
42
+ #
43
+ # Groups can be created with a gidnumber attribute, which is used when mapping LDAP/ActiveDirectory groups
44
+ # to Conjur groups, and when performing PAM authentication to assign a unix GID.
45
+ #
46
+ #
47
+ # @example
48
+ # group = api.create_group 'cats'
49
+ # puts group.attributes
50
+ # # Output
51
+ # {"id"=>"cats",
52
+ # "userid"=>"admin",
53
+ # "ownerid"=>"conjur:user:admin",
54
+ # "gidnumber"=>nil,
55
+ # "roleid"=>"conjur:group:cats",
56
+ # "resource_identifier"=>"conjur:group:cats"}
57
+ #
58
+ # @example Create a group with a GID number.
59
+ # group = api.create_group 'dogs', gidnumber: 1337
60
+ # puts group.attributes['gidnumber']
61
+ # # Output
62
+ # 1337
63
+ #
64
+ # @param [String] id the identifier for this group
65
+ # @param [Hash] options options for group creation
66
+ # @option options [FixNum] :gidnumber gidnumber to assign to this group (if not present, the
67
+ # group will *not* have a gidnumber, in contrast to Conjur {Conjur::User} instances).
68
+ # @return [Conjur::Group] the group created.
28
69
  def create_group(id, options = {})
29
70
  standard_create Conjur::Core::API.host, :group, id, options
30
71
  end
31
72
 
73
+
74
+ # Fetch a group with the given id. Note that the id is *unqualified* -- it must not contain
75
+ # `account` or `id` parts. For example,
76
+ #
77
+ # @example
78
+ # group = api.create_group 'fish'
79
+ # right = api.group 'fish'
80
+ # wrong = api.group 'conjur:group:fish'
81
+ # right.exists? # => true
82
+ # wrong.exists? # => false
83
+ #
84
+ # @param [String] id the identifier of the group
85
+ # @return [Conjur::Group] the group, which may or may not exist (you must check this using the {Conjur::Exists#exists?})
86
+ # method.
32
87
  def group id
33
88
  standard_show Conjur::Core::API.host, :group, id
34
89
  end
35
90
 
36
- # Find groups by GID.
91
+ # Find groups by GID. Note that gidnumbers are *not* unique for groups.
92
+ #
93
+ # @example
94
+ # dogs = api.create_group 'dogs', gidnumber: 42
95
+ # cats = api.create_group 'cats', gidnumber: 42
96
+ # api.find_groups gidnumber: 42
97
+ # # => ['cats', 'dogs']
98
+ #
99
+ # @example
100
+ # groups = api.find_groups(gidnumber: 42).map{|id| api.group(id)}
101
+ # groups.map(&:class) # => [Conjur::Group, Conjur::Group]
37
102
  #
38
103
  # @param [Hash] options search criteria
39
104
  # @option options [Integer] :gidnumber GID number
40
105
  # @return [Array<String>] group names matching the criteria
41
- #
42
- # @note You can get a {Conjur::Group} by calling {Conjur::API#group}, eg.:
43
- # +api.find_groups(gidnumber: 12345).map(&api.method(:group))+
44
106
  def find_groups options
45
107
  JSON.parse(RestClient::Resource.new(Conjur::Core::API.host, credentials)["groups/search?#{options.to_query}"].get)
46
108
  end
109
+ #@!endgroup
47
110
  end
48
111
  end