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.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +0 -1
- data/README.md +59 -18
- data/conjur-api.gemspec +2 -1
- data/lib/conjur/acts_as_asset.rb +6 -9
- data/lib/conjur/acts_as_role.rb +54 -7
- data/lib/conjur/annotations.rb +52 -14
- data/lib/conjur/api/audit.rb +54 -8
- data/lib/conjur/api/authn.rb +54 -9
- data/lib/conjur/api/groups.rb +67 -4
- data/lib/conjur/api/hosts.rb +62 -3
- data/lib/conjur/api/layers.rb +48 -3
- data/lib/conjur/api/pubkeys.rb +140 -9
- data/lib/conjur/api.rb +13 -1
- data/lib/conjur/base.rb +93 -6
- data/lib/conjur/configuration.rb +247 -20
- data/lib/conjur/exists.rb +26 -0
- data/lib/conjur/group.rb +50 -4
- data/lib/conjur/has_attributes.rb +66 -5
- data/lib/conjur/resource.rb +155 -13
- data/lib/conjur/role.rb +1 -1
- data/lib/conjur/standard_methods.rb +7 -2
- data/lib/conjur/variable.rb +168 -6
- data/lib/conjur-api/version.rb +1 -1
- data/lib/conjur-api.rb +2 -0
- data/spec/api/authn_spec.rb +6 -3
- data/spec/api/groups_spec.rb +1 -1
- data/spec/api/pubkeys_spec.rb +4 -4
- data/spec/api/roles_spec.rb +4 -2
- data/spec/api/users_spec.rb +2 -2
- data/spec/api/variables_spec.rb +1 -1
- data/spec/helpers/errors_matcher.rb +34 -0
- data/spec/helpers/request_helpers.rb +10 -0
- data/spec/lib/annotations_spec.rb +5 -2
- data/spec/lib/audit_spec.rb +5 -5
- data/spec/lib/group_spec.rb +1 -1
- data/spec/lib/resource_spec.rb +11 -11
- data/spec/lib/role_spec.rb +8 -7
- data/spec/lib/user_spec.rb +7 -3
- data/spec/ssl_spec.rb +85 -0
- data/spec/standard_methods_helper.rb +2 -0
- data/spec/variable_spec.rb +5 -3
- metadata +34 -7
- data/lib/conjur/patches/rest-client.rb +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa094471717dc9bb39477d76468d2663895d9fd4
|
4
|
+
data.tar.gz: d688adf16203e25c50646994bc619170d5633b89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Programmatic Ruby access to the Conjur API.
|
4
4
|
|
5
|
-
|
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
|
-
|
19
|
+
# Usage
|
20
20
|
|
21
|
-
|
21
|
+
Connecting to Conjur is a two-step process:
|
22
22
|
|
23
|
-
|
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
|
-
|
27
|
-
Conjur.
|
40
|
+
require 'conjur/cli'
|
41
|
+
Conjur::Config.load
|
42
|
+
Conjur::Config.apply
|
28
43
|
```
|
29
44
|
|
30
|
-
|
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
|
-
|
48
|
+
## Authentication
|
49
|
+
|
50
|
+
Once Conjur is configured, the connection can be established like this:
|
33
51
|
|
34
52
|
```ruby
|
35
|
-
|
53
|
+
conjur = Conjur::Authn.connect nil, noask: true
|
36
54
|
```
|
37
55
|
|
38
|
-
|
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
|
-
|
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
|
-
|
44
|
-
Conjur
|
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
|
-
|
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
|
-
|
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
|
-
|
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', '
|
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
|
data/lib/conjur/acts_as_asset.rb
CHANGED
@@ -20,15 +20,12 @@
|
|
20
20
|
#
|
21
21
|
module Conjur
|
22
22
|
module ActsAsAsset
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
data/lib/conjur/acts_as_role.rb
CHANGED
@@ -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
|
-
#
|
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
|
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
|
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
|
data/lib/conjur/annotations.rb
CHANGED
@@ -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
|
-
#
|
24
|
-
#
|
30
|
+
# with {#[]} and update with {#[]=}, {#each} it, and {#merge!} to do bulk updates.
|
31
|
+
#
|
25
32
|
class Annotations
|
26
33
|
include Enumerable
|
27
|
-
|
28
|
-
#
|
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
|
56
|
-
#
|
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
|
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|
|
data/lib/conjur/api/audit.rb
CHANGED
@@ -20,24 +20,70 @@
|
|
20
20
|
|
21
21
|
require 'conjur/event_source'
|
22
22
|
module Conjur
|
23
|
+
|
24
|
+
|
23
25
|
class API
|
24
|
-
|
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
|
30
|
-
#
|
31
|
-
#
|
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)
|
data/lib/conjur/api/authn.rb
CHANGED
@@ -23,7 +23,28 @@ require 'conjur/user'
|
|
23
23
|
module Conjur
|
24
24
|
class API
|
25
25
|
class << self
|
26
|
-
|
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
|
-
#
|
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
|
-
#
|
60
|
-
#
|
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}"
|
data/lib/conjur/api/groups.rb
CHANGED
@@ -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
|