conjur-api 4.26.0 → 4.28.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/features/bootstrap.feature +3 -0
- data/lib/conjur-api/version.rb +1 -1
- data/lib/conjur/api/ldapsync.rb +60 -22
- data/lib/conjur/api/resources.rb +27 -0
- data/lib/conjur/api/roles.rb +2 -2
- data/lib/conjur/bootstrap.rb +5 -0
- data/lib/conjur/ldap_sync_job.rb +89 -0
- data/lib/conjur/resource.rb +1 -1
- data/lib/conjur/role.rb +2 -3
- data/spec/api/ldapsync_spec.rb +24 -55
- data/spec/api/resources_spec.rb +36 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 038dcc4d85e30d07b34ca84dda11196b3cbc8a98
|
4
|
+
data.tar.gz: 7b47721f2a9af64c512c6c2fbc5a5644aa5d98e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d4dc629522aa37aeea760aa16ec9d9df7694754fe5490f45530de68bcba544a9b35de834288dd4576920a92b800be71fe3a03414397be0e24bd06a954929fe0
|
7
|
+
data.tar.gz: dafee7953f111a1723a22f9cc0b2a2dacd970e6c10fad46f20458380fb14951ff7ef0e83a09027aa9e3cb20d0fc993a39e6872bfce2fc46e536879ab356f2c73
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
# v4.28.0
|
2
|
+
|
3
|
+
* Add `Conjur::API#ldap_sync_policy` to fetch the policy to use to
|
4
|
+
bring Conjur and the LDAP server into sync.
|
5
|
+
|
6
|
+
* Remove `Conjur::API#ldap_sync_now` and `Conjur::API#ldap_sync_jobs`
|
7
|
+
|
8
|
+
# v4.27.0
|
9
|
+
|
10
|
+
* Add `Conjur::API#resources_permitted?"
|
11
|
+
|
12
|
+
* `Conjur::API#ldap_sync_now` now accepts an options Hash which will
|
13
|
+
be passed on to the `/sync` entrypoint. The old argument list is
|
14
|
+
maintained for backwards compatibility.
|
15
|
+
|
16
|
+
* `Conjur::Api#resources` now supports `:has_annotation` for
|
17
|
+
retrieving Conjur resources that have an annotation with the given
|
18
|
+
name.
|
19
|
+
|
1
20
|
# v4.26.0
|
2
21
|
|
3
22
|
* expose admin_option in the role graph (only populated by Conjur 4.8 and later)
|
data/features/bootstrap.feature
CHANGED
@@ -17,6 +17,9 @@ Feature: conjur bootstrap
|
|
17
17
|
Scenario: security_admin group has the expected members
|
18
18
|
Then expressions "$conjur.role('group:security_admin').members.map(&:member).map(&:roleid).sort.join(',')" and "'cucumber:host:conjur/authn-tv,cucumber:host:conjur/expiration,cucumber:host:conjur/ldap-sync,cucumber:host:conjur/policy-loader,cucumber:host:conjur/secrets-rotator,cucumber:user:admin'" are equal
|
19
19
|
|
20
|
+
Scenario: security_admin group can update public keys
|
21
|
+
Then expression "$conjur.resource('service:pubkeys-1.0/public-keys').permitted_roles('update')" includes "$conjur.group('security_admin').roleid"
|
22
|
+
|
20
23
|
Scenario: security_admin can 'elevate' and 'reveal'
|
21
24
|
Then expression "$conjur.resource('!:!:conjur').permitted_roles('elevate')" includes "$conjur.group('security_admin').roleid"
|
22
25
|
Then expression "$conjur.resource('!:!:conjur').permitted_roles('reveal')" includes "$conjur.group('security_admin').roleid"
|
data/lib/conjur-api/version.rb
CHANGED
data/lib/conjur/api/ldapsync.rb
CHANGED
@@ -18,36 +18,74 @@
|
|
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/ldap_sync_job'
|
21
22
|
|
22
23
|
module Conjur
|
23
24
|
class API
|
24
|
-
|
25
|
+
# @!group LDAP Sync Service
|
25
26
|
|
26
|
-
#
|
27
|
-
|
28
|
-
#
|
29
|
-
# @param [
|
30
|
-
# @param [
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
h[:headers][:accept] =
|
27
|
+
# Fetch a Conjur policy that will bring Conjur into sync with the
|
28
|
+
# LDAP server specified by a profile.
|
29
|
+
#
|
30
|
+
# @param [String] profile the name of the LDAP server profile
|
31
|
+
# @param [Hash] options reserved for future use
|
32
|
+
def ldap_sync_policy profile, options = {}
|
33
|
+
|
34
|
+
headers = credentials.dup.tap {|h|
|
35
|
+
h[:headers][:accept] = 'text/event-stream'
|
35
36
|
}
|
36
37
|
|
37
|
-
|
38
|
+
options = options.merge(:config_name => profile)
|
39
|
+
url = Conjur.configuration.appliance_url + "/ldap-sync/policy?#{options.to_query}"
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
41
|
+
# Even though we're using SSE to return the policy, fetch the
|
42
|
+
# whole thing at once into a single response. Retrieving it in
|
43
|
+
# chunks doesn't buy us much of anything except more complicated
|
44
|
+
# client code.
|
45
|
+
response = RestClient::Resource.new(url, headers).get
|
46
|
+
|
47
|
+
json = if response.headers[:content_type] == 'text/event-stream'
|
48
|
+
find_policy_event(response) || find_error_events(response)
|
49
|
+
else
|
50
|
+
%Q({"error": {"message": "Unexpected response from server: #{response.body}"}})
|
51
|
+
end
|
52
|
+
JSON.parse(json)
|
53
|
+
end
|
54
|
+
|
55
|
+
# @api private
|
56
|
+
# Get an LDAP sync profile.
|
57
|
+
|
58
|
+
# @param [String] profile name
|
59
|
+
# @param [Hash] options reserved
|
60
|
+
def ldap_sync_show_profile(profile, options = {})
|
61
|
+
resp = RestClient::Resource.new(Conjur.configuration.appliance_url, credentials)['ldap-sync']['config'].get(options)
|
62
|
+
JSON.parse(resp.body)
|
63
|
+
end
|
64
|
+
|
65
|
+
# @api private
|
66
|
+
# Update an LDAP sync profile.
|
67
|
+
#
|
68
|
+
# ### Note
|
69
|
+
# DO NOT use this method and the UI to update an LDAP sync profile.
|
70
|
+
#
|
71
|
+
# @param [Hash] profile a hash containing the LDAP sync configuration
|
72
|
+
# @param [Hash] options reserved
|
73
|
+
def ldap_sync_update_profile(profile, options = {})
|
74
|
+
options[:json_config] = profile.to_json
|
75
|
+
resp = RestClient::Resource.new(Conjur.configuration.appliance_url, credentials)['ldap-sync']['config'].put(options.to_json, :content_type => 'application/json')
|
76
|
+
JSON.parse(resp.body)
|
77
|
+
end
|
78
|
+
|
79
|
+
# @!endgroup
|
80
|
+
|
81
|
+
private
|
82
|
+
def find_policy_event(response)
|
83
|
+
response.body.lines.find {|l| l =~ /^data: {"policy":/}.try(:[], 6..-1)
|
84
|
+
end
|
85
|
+
|
86
|
+
def find_error_events(response)
|
87
|
+
response.body.lines.collect {|l| l.match(/^data: ({"error":.*)/).try(:[], 1)}.compact.join("\n")
|
49
88
|
end
|
50
89
|
|
51
|
-
# @!endgroup
|
52
90
|
end
|
53
91
|
end
|
data/lib/conjur/api/resources.rb
CHANGED
@@ -166,5 +166,32 @@ module Conjur
|
|
166
166
|
def global_privilege_permitted? privilege
|
167
167
|
resource(GLOBAL_PRIVILEGE_RESOURCE).permitted? privilege
|
168
168
|
end
|
169
|
+
|
170
|
+
# Check to see if the logged-in role has the specified +privilege+
|
171
|
+
# on the resources specified by +kind+ and +identifiers+.
|
172
|
+
#
|
173
|
+
# @example
|
174
|
+
# secret1 = api.create_variable 'text/plain', 'secret1', id: 'secret1', value: 'my_first_secret'
|
175
|
+
# secret2 = api.create_variable 'text/plain', 'secret2', id: 'secret2', value: 'another_secret'
|
176
|
+
# all_permitted, results = api.resources_permitted? 'variable', ['secret1', 'secret2'], 'execute'
|
177
|
+
|
178
|
+
# @param [String] kind the kind of resources to check
|
179
|
+
# @param [Array<String>] identifiers the (unqualified) identifiers of the resources
|
180
|
+
# @param [String] privilege the privilege to check for
|
181
|
+
# @return [Array] first element is a Boolean, true if all checks passed, false otherwise.
|
182
|
+
# If some checks fail, second element is the check result for each resource.
|
183
|
+
def resources_permitted? kind, identifiers, privilege
|
184
|
+
options = {
|
185
|
+
privilege: privilege,
|
186
|
+
identifiers: identifiers
|
187
|
+
}
|
188
|
+
resp = RestClient::Resource.new(Conjur::Authz::API.host, credentials)["#{Conjur.account}/resources/#{kind}?check=true"].post(options)
|
189
|
+
if resp.code == 204
|
190
|
+
[true, []]
|
191
|
+
else
|
192
|
+
[false, JSON.parse(resp.body)]
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
169
196
|
end
|
170
197
|
end
|
data/lib/conjur/api/roles.rb
CHANGED
@@ -31,8 +31,8 @@ module Conjur
|
|
31
31
|
# @param [Array<Conjur::Role, String>, String, Conjur::Role] roles role or or array of roles
|
32
32
|
# roles whose relationships we're interested in
|
33
33
|
# @param [Hash] options options for the request
|
34
|
-
# @option options [Boolean] :ancestors Whether to return ancestors of the given roles (true by default)
|
35
|
-
# @option options [Boolean] :descendants Whether to return descendants of the given roles (true by default)
|
34
|
+
# @option options [Boolean] :ancestors Whether to return ancestors ("roles that your role has") of the given roles (true by default)
|
35
|
+
# @option options [Boolean] :descendants Whether to return descendants ("roles that have your role") of the given roles (true by default)
|
36
36
|
# @option options [Conjur::Role, String] :as_role Only roles visible to this role will be included in the graph
|
37
37
|
# @return [Conjur::Graph] An object representing the role memberships digraph
|
38
38
|
def role_graph roles, options = {}
|
data/lib/conjur/bootstrap.rb
CHANGED
@@ -84,6 +84,7 @@ module Conjur
|
|
84
84
|
class Pubkeys < Base
|
85
85
|
def perform
|
86
86
|
find_or_create_record key_managers, security_admin
|
87
|
+
|
87
88
|
find_or_create_record pubkeys_layer, security_admin
|
88
89
|
find_or_create_record pubkeys_host, security_admin do |record, options|
|
89
90
|
api.create_host(id: record.id, ownerid: security_admin.roleid)
|
@@ -91,7 +92,11 @@ module Conjur
|
|
91
92
|
pubkeys_layer.add_host pubkeys_host unless pubkeys_layer.hosts.map(&:roleid).member?(pubkeys_host.roleid)
|
92
93
|
|
93
94
|
find_or_create_resource pubkeys_service, security_admin
|
95
|
+
|
94
96
|
permit pubkeys_service, 'update', key_managers
|
97
|
+
|
98
|
+
# also permit security_admin to update public keys
|
99
|
+
permit pubkeys_service, 'update', security_admin
|
95
100
|
end
|
96
101
|
|
97
102
|
def pubkeys_layer
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'conjur/event_source'
|
2
|
+
|
3
|
+
module Conjur
|
4
|
+
class LdapSyncJob
|
5
|
+
|
6
|
+
attr_reader :hash
|
7
|
+
|
8
|
+
# Creates a new `LdapSyncJob` from a Hash as returned
|
9
|
+
# by the LDAP sync service's `GET /jobs` route.
|
10
|
+
def self.new_from_json api, hash
|
11
|
+
new(api, hash)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize api, hash
|
15
|
+
@api = api
|
16
|
+
@hash = hash.with_indifferent_access
|
17
|
+
end
|
18
|
+
|
19
|
+
def exclusive?
|
20
|
+
self.exclusive
|
21
|
+
end
|
22
|
+
|
23
|
+
def [](k)
|
24
|
+
@hash[k]
|
25
|
+
end
|
26
|
+
|
27
|
+
def method_missing(sym, *arguments, &block)
|
28
|
+
@hash[sym]
|
29
|
+
end
|
30
|
+
|
31
|
+
# Stop this job (if running) and remove it from the list of jobs.
|
32
|
+
def delete
|
33
|
+
job_resource.delete
|
34
|
+
end
|
35
|
+
|
36
|
+
# Receive output from this job and pass them to the given block.
|
37
|
+
def output &block
|
38
|
+
events = []
|
39
|
+
wrapper = lambda do |e|
|
40
|
+
events << e
|
41
|
+
block[e] if block
|
42
|
+
end
|
43
|
+
|
44
|
+
follow_job_output(&wrapper)
|
45
|
+
|
46
|
+
events
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_s
|
50
|
+
"<LdapSyncJob #{id} type=#{type} state=#{state}#{exclusive? ? ' exclusive' : ''}>"
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_h
|
54
|
+
@hash
|
55
|
+
end
|
56
|
+
|
57
|
+
alias as_json to_h
|
58
|
+
|
59
|
+
def to_json _unused
|
60
|
+
as_json.to_json
|
61
|
+
end
|
62
|
+
private
|
63
|
+
|
64
|
+
def follow_job_output &block
|
65
|
+
options = @api.credentials.dup.tap{|h| h[:headers][:accept] = 'text/event-stream'}
|
66
|
+
|
67
|
+
handle_response = lambda do |response|
|
68
|
+
response.error! unless response.code == '200'
|
69
|
+
es = EventSource.new
|
70
|
+
es.message{ |e| block[e.data] }
|
71
|
+
|
72
|
+
response.read_body do |chunk|
|
73
|
+
es.feed chunk
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
RestClient::Request.execute(
|
78
|
+
url: "#{job_resource['output'].url}",
|
79
|
+
headers: options[:headers],
|
80
|
+
method: :get,
|
81
|
+
block_response: handle_response
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
def job_resource
|
86
|
+
RestClient::Resource.new(Conjur.configuration.appliance_url, @api.credentials)['ldap-sync']['jobs'][id]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/conjur/resource.rb
CHANGED
@@ -282,7 +282,7 @@ module Conjur
|
|
282
282
|
|
283
283
|
path = "#{account}/resources"
|
284
284
|
path += "/#{kind}" if kind
|
285
|
-
query = opts.slice(:acting_as, :limit, :offset, :search)
|
285
|
+
query = opts.slice(:acting_as, :limit, :offset, :search, :has_annotation)
|
286
286
|
path += "?#{query.to_query}" unless query.empty?
|
287
287
|
resource = RestClient::Resource.new(host, credentials)[path]
|
288
288
|
|
data/lib/conjur/role.rb
CHANGED
@@ -76,8 +76,7 @@ module Conjur
|
|
76
76
|
# so if `a` is a member of `b`, and `b` is a member of `c`, `a.all` will include `c`.
|
77
77
|
#
|
78
78
|
# ### Permissions
|
79
|
-
# You must be a member of the role to call this method
|
80
|
-
# a member of every role).
|
79
|
+
# You must be a member of the role to call this method.
|
81
80
|
#
|
82
81
|
# You can restrict the roles returned to one or more role ids. This feature is mainly useful
|
83
82
|
# for checking whether this role is a member of any of a set of roles.
|
@@ -92,7 +91,7 @@ module Conjur
|
|
92
91
|
# # => ["conjur:group:pubkeys-1.0/admin", "conjur:user:alice"]
|
93
92
|
#
|
94
93
|
# @example See if role `"conjur:user:alice"` is a member of either `"conjur:groups:developers"` or `"conjur:group:ops"`
|
95
|
-
# is_member =
|
94
|
+
# is_member = api.role('conjur:user:alice').all(filter: ['conjur:group:developers', 'conjur:group:ops']).any?
|
96
95
|
#
|
97
96
|
# @param [Hash] options options for the request
|
98
97
|
# @option options [String, #roleid, Array<String, #roleid>] :filter only return roles in this list
|
data/spec/api/ldapsync_spec.rb
CHANGED
@@ -12,64 +12,33 @@ require 'helpers/request_helpers'
|
|
12
12
|
|
13
13
|
describe Conjur::API, api: :dummy do
|
14
14
|
include RequestHelpers
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
{
|
20
|
-
:okay => true,
|
21
|
-
:result => {
|
22
|
-
:actions => [
|
23
|
-
"Create user 'Guest'\n Set annotation 'ldap-sync/source'\n Set annotation 'ldap-sync/upstream-dn'"
|
24
|
-
]
|
25
|
-
}
|
26
|
-
}
|
27
|
-
}
|
28
|
-
let(:response){ double('response', body: response_json.to_json) }
|
29
|
-
let(:dry_run) { true }
|
30
|
-
|
31
|
-
before do
|
32
|
-
allow(Conjur.configuration).to receive(:appliance_url).and_return appliance_url
|
33
|
-
allow(Conjur::API).to receive_messages(ldap_sync_now: ldapsync_url)
|
34
|
-
expect_request(
|
35
|
-
url: ldapsync_url,
|
36
|
-
method: :post,
|
37
|
-
headers: credentials[:headers],
|
38
|
-
payload: {config_name: 'default', dry_run: dry_run}
|
39
|
-
).and_return response
|
40
|
-
end
|
41
|
-
|
42
|
-
describe "#ldap_sync_now" do
|
43
|
-
it "POSTs /sync" do
|
44
|
-
api.ldap_sync_now('default', 'application/json', true)
|
15
|
+
describe 'LDAP policy methods' do
|
16
|
+
let(:appliance_url){ "http://example.com/api" }
|
17
|
+
before do
|
18
|
+
allow(Conjur.configuration).to receive(:appliance_url).and_return appliance_url
|
45
19
|
end
|
46
|
-
end
|
47
20
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
21
|
+
describe '#ldap_sync_policy' do
|
22
|
+
let(:profile) { 'default' }
|
23
|
+
let(:url){ "#{appliance_url}/ldap-sync/policy?config_name=#{profile}" }
|
24
|
+
let(:policy_event){
|
25
|
+
%Q{data: {"policy": "a policy"}}
|
26
|
+
}
|
27
|
+
|
28
|
+
let(:response){ double('response', :body => policy_event, :headers => { :content_type => 'text/event-stream' }) }
|
29
|
+
subject{ api.ldap_sync_policy('default') }
|
30
|
+
before do
|
31
|
+
expect_request(
|
32
|
+
url: url,
|
33
|
+
method: :get,
|
34
|
+
headers: credentials[:headers]
|
35
|
+
).and_return response
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns a Hash with a policy' do
|
39
|
+
expect(subject).to be_kind_of Hash
|
40
|
+
end
|
52
41
|
end
|
53
|
-
end
|
54
42
|
|
55
|
-
describe "#ldap_sync_now" do
|
56
|
-
let(:dry_run) { false }
|
57
|
-
it "POSTs /sync with dry_run set to false" do
|
58
|
-
api.ldap_sync_now('default', 'application/json', false)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
describe "#ldap_sync_now" do
|
63
|
-
let(:dry_run) { true }
|
64
|
-
it "POSTs /sync with truthy dry_run value" do
|
65
|
-
api.ldap_sync_now('default', 'application/json', 1)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
describe "#ldap_sync_now" do
|
70
|
-
let(:dry_run) { false }
|
71
|
-
it "POSTs /sync with falsey dry_run value" do
|
72
|
-
api.ldap_sync_now('default', 'application/json', nil)
|
73
|
-
end
|
74
43
|
end
|
75
44
|
end
|
data/spec/api/resources_spec.rb
CHANGED
@@ -44,4 +44,40 @@ describe Conjur::API, api: :dummy do
|
|
44
44
|
expect(api.resources(kind: :chunky).map(&:url)).to eql(ids.map { |id| api.resource(id).url })
|
45
45
|
end
|
46
46
|
end
|
47
|
+
|
48
|
+
describe '#resources_permitted' do
|
49
|
+
let(:ids) { %w(foo bar baz) }
|
50
|
+
let(:kind) { 'variable' }
|
51
|
+
let(:priv) { 'execute' }
|
52
|
+
|
53
|
+
it 'creates the request correctly' do
|
54
|
+
expect_request(
|
55
|
+
method: :post,
|
56
|
+
url: "#{authz_host}/the-account/resources/#{kind}?check=true",
|
57
|
+
payload: {
|
58
|
+
:privilege => priv,
|
59
|
+
:identifiers => ids
|
60
|
+
}
|
61
|
+
).and_return(double("response", :code => 204))
|
62
|
+
|
63
|
+
res = api.resources_permitted?(kind, ids, priv)
|
64
|
+
expect(res[0]).to be(true)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'signals failure' do
|
68
|
+
expect_request(
|
69
|
+
method: :post,
|
70
|
+
url: "#{authz_host}/the-account/resources/#{kind}?check=true",
|
71
|
+
payload: {
|
72
|
+
:privilege => priv,
|
73
|
+
:identifiers => ids
|
74
|
+
}
|
75
|
+
).and_return(double("response", :code => 403, :body => '[]'))
|
76
|
+
|
77
|
+
res = api.resources_permitted?(kind, ids, priv)
|
78
|
+
expect(res[0]).to be(false)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
47
83
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: conjur-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.28.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rafal Rzepecki
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-11-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rest-client
|
@@ -383,6 +383,7 @@ files:
|
|
383
383
|
- lib/conjur/host_factory_token.rb
|
384
384
|
- lib/conjur/layer-api.rb
|
385
385
|
- lib/conjur/layer.rb
|
386
|
+
- lib/conjur/ldap_sync_job.rb
|
386
387
|
- lib/conjur/log.rb
|
387
388
|
- lib/conjur/log_source.rb
|
388
389
|
- lib/conjur/path_based.rb
|