conjur-api 4.31.0 → 5.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.dockerignore +1 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +22 -3
- data/Dockerfile +12 -3
- data/Gemfile +3 -3
- data/Jenkinsfile +69 -0
- data/LICENSE.md +195 -0
- data/README.md +16 -0
- data/Rakefile +34 -18
- data/ci/wait_for_server.sh +10 -0
- data/conjur-api.gemspec +6 -14
- data/dev/docker-compose.yml +23 -0
- data/dev/empty.yml +2 -0
- data/dev/start.sh +15 -0
- data/dev/stop.sh +6 -0
- data/docker-compose.yml +27 -0
- data/features/exists.feature +37 -0
- data/features/group.feature +11 -0
- data/features/host.feature +20 -0
- data/features/host_factory_create_host.feature +28 -0
- data/features/host_factory_token.feature +63 -0
- data/features/load_policy.feature +61 -0
- data/features/members.feature +51 -0
- data/features/new_api.feature +36 -0
- data/features/permitted.feature +43 -0
- data/features/permitted_roles.feature +30 -0
- data/features/public_keys.feature +11 -0
- data/features/resource_fields.feature +53 -0
- data/features/role_fields.feature +15 -0
- data/features/rotate_api_key.feature +13 -0
- data/features/step_definitions/api_steps.rb +4 -54
- data/features/step_definitions/policy_steps.rb +35 -0
- data/features/step_definitions/result_steps.rb +7 -0
- data/features/support/env.rb +14 -5
- data/features/support/hooks.rb +3 -0
- data/features/support/world.rb +5 -6
- data/features/update_password.feature +14 -0
- data/features/user.feature +17 -0
- data/features/variable_fields.feature +20 -0
- data/features/variable_value.feature +67 -0
- data/lib/conjur/acts_as_resource.rb +95 -65
- data/lib/conjur/acts_as_role.rb +102 -51
- data/lib/conjur/{audit-api.rb → acts_as_rolsource.rb} +10 -14
- data/lib/conjur/acts_as_user.rb +13 -22
- data/lib/conjur/api/authn.rb +37 -72
- data/lib/conjur/api/host_factories.rb +35 -55
- data/lib/conjur/api/policies.rb +56 -0
- data/lib/conjur/api/pubkeys.rb +36 -160
- data/lib/conjur/api/resources.rb +32 -116
- data/lib/conjur/api/roles.rb +28 -105
- data/lib/conjur/api/variables.rb +22 -91
- data/lib/conjur/api.rb +19 -46
- data/lib/conjur/base.rb +21 -132
- data/lib/conjur/base_object.rb +57 -0
- data/lib/conjur/{authn-api.rb → build_object.rb} +23 -11
- data/lib/conjur/cast.rb +12 -17
- data/lib/conjur/cert_utils.rb +1 -1
- data/lib/conjur/cidr.rb +1 -1
- data/lib/conjur/configuration.rb +13 -91
- data/lib/conjur/escape.rb +1 -2
- data/lib/conjur/group.rb +9 -65
- data/lib/conjur/has_attributes.rb +22 -59
- data/lib/conjur/host.rb +5 -35
- data/lib/conjur/host_factory.rb +40 -40
- data/lib/conjur/host_factory_token.rb +38 -23
- data/lib/conjur/id.rb +63 -0
- data/lib/conjur/layer.rb +5 -80
- data/lib/conjur/log.rb +1 -1
- data/lib/conjur/log_source.rb +1 -1
- data/lib/conjur/{secret.rb → policy.rb} +11 -14
- data/lib/conjur/{api/secrets.rb → policy_load_result.rb} +35 -22
- data/lib/conjur/query_string.rb +2 -1
- data/lib/conjur/resource.rb +5 -299
- data/lib/conjur/role.rb +5 -317
- data/lib/conjur/role_grant.rb +20 -28
- data/lib/conjur/user.rb +5 -63
- data/lib/conjur/variable.rb +31 -76
- data/lib/conjur/{authz-api.rb → webservice.rb} +8 -16
- data/lib/conjur-api/version.rb +2 -2
- data/publish.sh +7 -0
- data/spec/api_spec.rb +208 -0
- data/spec/cast_spec.rb +21 -0
- data/spec/{lib/cert_utils_spec.rb → cert_utils_spec.rb} +0 -0
- data/spec/{lib/cidr_spec.rb → cidr_spec.rb} +0 -0
- data/spec/{lib/configuration_spec.rb → configuration_spec.rb} +40 -140
- data/spec/{lib/has_attributes_spec.rb → has_attributes_spec.rb} +6 -2
- data/spec/{lib/log_source_spec.rb → log_source_spec.rb} +0 -0
- data/spec/{lib/log_spec.rb → log_spec.rb} +0 -0
- data/spec/roles_spec.rb +24 -0
- data/spec/spec_helper.rb +63 -78
- data/spec/ssl_spec.rb +3 -5
- data/spec/vendor/rest_client_spec.rb +0 -54
- data/test.sh +40 -0
- metadata +122 -281
- data/.kateproject +0 -5
- data/LICENSE +0 -22
- data/ci/test.sh +0 -9
- data/features/audit_resources.feature +0 -15
- data/features/audit_roles.feature +0 -15
- data/features/bootstrap.feature +0 -31
- data/features/step_definitions/cli_steps.rb +0 -5
- data/jenkins.sh +0 -27
- data/lib/conjur/acts_as_asset.rb +0 -88
- data/lib/conjur/annotations.rb +0 -186
- data/lib/conjur/api/audit.rb +0 -138
- data/lib/conjur/api/deputies.rb +0 -57
- data/lib/conjur/api/groups.rb +0 -111
- data/lib/conjur/api/hosts.rb +0 -109
- data/lib/conjur/api/info.rb +0 -126
- data/lib/conjur/api/layers.rb +0 -62
- data/lib/conjur/api/ldapsync.rb +0 -115
- data/lib/conjur/api/users.rb +0 -106
- data/lib/conjur/bootstrap.rb +0 -161
- data/lib/conjur/build_from_response.rb +0 -49
- data/lib/conjur/core-api.rb +0 -74
- data/lib/conjur/deputy.rb +0 -55
- data/lib/conjur/env.rb +0 -54
- data/lib/conjur/event_source.rb +0 -101
- data/lib/conjur/exists.rb +0 -60
- data/lib/conjur/graph.rb +0 -295
- data/lib/conjur/has_id.rb +0 -43
- data/lib/conjur/has_identifier.rb +0 -36
- data/lib/conjur/has_owner.rb +0 -51
- data/lib/conjur/host-factory-api.rb +0 -38
- data/lib/conjur/layer-api.rb +0 -13
- data/lib/conjur/ldap_sync_job.rb +0 -89
- data/lib/conjur/path_based.rb +0 -86
- data/lib/conjur/pubkeys-api.rb +0 -50
- data/lib/conjur/standard_methods.rb +0 -91
- data/reqspeed.rb +0 -20
- data/spec/api/authn_spec.rb +0 -81
- data/spec/api/graph_spec.rb +0 -117
- data/spec/api/groups_spec.rb +0 -40
- data/spec/api/hosts_spec.rb +0 -36
- data/spec/api/info_spec.rb +0 -89
- data/spec/api/layer_spec.rb +0 -18
- data/spec/api/ldapsync_spec.rb +0 -44
- data/spec/api/pubkeys_spec.rb +0 -66
- data/spec/api/resources_spec.rb +0 -92
- data/spec/api/roles_spec.rb +0 -100
- data/spec/api/secrets_spec.rb +0 -16
- data/spec/api/users_spec.rb +0 -71
- data/spec/api/variables_spec.rb +0 -112
- data/spec/cas_rest_client.rb +0 -17
- data/spec/cidr_helper.rb +0 -24
- data/spec/lib/acts_as_user_spec.rb +0 -27
- data/spec/lib/annotations_spec.rb +0 -109
- data/spec/lib/api_spec.rb +0 -480
- data/spec/lib/asset_spec.rb +0 -80
- data/spec/lib/audit_spec.rb +0 -155
- data/spec/lib/build_from_response_spec.rb +0 -49
- data/spec/lib/deputy_spec.rb +0 -25
- data/spec/lib/exists_spec.rb +0 -24
- data/spec/lib/group_spec.rb +0 -18
- data/spec/lib/host_spec.rb +0 -31
- data/spec/lib/resource_spec.rb +0 -240
- data/spec/lib/role_grant_spec.rb +0 -13
- data/spec/lib/role_spec.rb +0 -231
- data/spec/lib/standard_methods_spec.rb +0 -66
- data/spec/lib/user_spec.rb +0 -77
- data/spec/standard_methods_helper.rb +0 -41
- data/spec/variable_spec.rb +0 -101
- data/spec/vcr_cassettes/Conjur_Resource/_create/with_path-like_identifier.yml +0 -87
- data/spec/vcr_cassettes/Conjur_Resource/_create/with_un-encoded_path-like_identifier.yml +0 -87
- data/spec/vcr_cassettes/Conjur_Resource/_create/with_uuid_identifier.yml +0 -87
data/lib/conjur/api/authn.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright
|
2
|
+
# Copyright 2013-2017 Conjur Inc
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
5
5
|
# this software and associated documentation files (the "Software"), to deal in
|
@@ -23,18 +23,16 @@ require 'conjur/user'
|
|
23
23
|
module Conjur
|
24
24
|
class API
|
25
25
|
class << self
|
26
|
-
#@!group Authentication
|
26
|
+
#@!group Authentication
|
27
27
|
|
28
|
-
#
|
29
|
-
# operation exchanges a username and a password for an api key. The api key
|
28
|
+
# Exchanges a username and a password for an api key. The api key
|
30
29
|
# is preferable for storage and use in code, as it can be rotated and has far greater entropy than
|
31
30
|
# a user memorizable password.
|
32
31
|
#
|
33
|
-
# * Note that this method works only for {
|
34
|
-
# {
|
35
|
-
#
|
36
|
-
# *
|
37
|
-
# * This method uses Basic Auth to send the credentials.
|
32
|
+
# * Note that this method works only for {Conjur::User}s. While
|
33
|
+
# {Conjur::Host}s are roles, they do not have passwords.
|
34
|
+
# * If you pass an api key to this method instead of a password, it will verify and return the API key.
|
35
|
+
# * This method uses HTTP Basic Authentication to send the credentials.
|
38
36
|
#
|
39
37
|
# @example
|
40
38
|
# bob_api_key = Conjur::API.login('bob', 'bob_password')
|
@@ -43,104 +41,71 @@ module Conjur
|
|
43
41
|
# @param [String] username The `username` or `login` for the
|
44
42
|
# {http://developer.conjur.net/reference/services/directory/user Conjur User}.
|
45
43
|
# @param [String] password The `password` or `api key` to authenticate with.
|
44
|
+
# @param [String] account The organization account.
|
46
45
|
# @return [String] the API key.
|
47
|
-
|
48
|
-
def login username, password
|
46
|
+
def login username, password, account: Conjur.configuration.account
|
49
47
|
if Conjur.log
|
50
|
-
Conjur.log << "Logging in #{username} via Basic authentication\n"
|
48
|
+
Conjur.log << "Logging in #{username} to account #{account} via Basic authentication\n"
|
51
49
|
end
|
52
|
-
RestClient::Resource.new(Conjur
|
50
|
+
RestClient::Resource.new(Conjur.configuration.authn_url, user: username, password: password)[fully_escape account]['login'].get
|
53
51
|
end
|
54
52
|
|
55
|
-
#
|
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
|
65
|
-
def login_cas username, password, cas_api_url
|
66
|
-
if Conjur.log
|
67
|
-
Conjur.log << "Logging in #{username} via CAS authentication\n"
|
68
|
-
end
|
69
|
-
require 'cas_rest_client'
|
70
|
-
client = CasRestClient.new(:username => username, :password => password, :uri => [ cas_api_url, 'v1', 'tickets' ].join('/'), :use_cookies => false)
|
71
|
-
client.get("#{Conjur::Authn::API.host}/users/login").body
|
72
|
-
end
|
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.
|
53
|
+
# Exchanges Conjur the API key (refresh token) for an access token. The access token can
|
54
|
+
# then be used to authenticate further API calls.
|
78
55
|
#
|
79
56
|
# @param [String] username The username or host id for which we want a token
|
80
|
-
# @param [String]
|
57
|
+
# @param [String] api_key The api key
|
58
|
+
# @param [String] account The organization account.
|
81
59
|
# @return [String] A JSON formatted authentication token.
|
82
|
-
def authenticate username,
|
60
|
+
def authenticate username, api_key, account: Conjur.configuration.account
|
61
|
+
account ||= Conjur.configuration.account
|
83
62
|
if Conjur.log
|
84
|
-
Conjur.log << "Authenticating #{username}\n"
|
63
|
+
Conjur.log << "Authenticating #{username} to account #{account}\n"
|
85
64
|
end
|
86
|
-
JSON::parse(RestClient::Resource.new(Conjur
|
65
|
+
JSON::parse(RestClient::Resource.new(Conjur.configuration.authn_url)[fully_escape account][fully_escape username]['authenticate'].post api_key, content_type: 'text/plain')
|
87
66
|
end
|
88
67
|
|
89
|
-
|
90
68
|
# Change a user's password. To do this, you must have the user's current password. This does not change or rotate
|
91
|
-
# api keys.
|
69
|
+
# api keys. However, you *can* use the user's api key as the *current* password, if the user was not created
|
92
70
|
# with a password.
|
93
71
|
#
|
94
|
-
# @param [String] username the name of the user whose password we want to change
|
95
|
-
# @param [String] password the user's *current* password *or* api key
|
72
|
+
# @param [String] username the name of the user whose password we want to change.
|
73
|
+
# @param [String] password the user's *current* password *or* api key.
|
96
74
|
# @param [String] new_password the new password for the user.
|
75
|
+
# @param [String] account The organization account.
|
97
76
|
# @return [void]
|
98
|
-
def update_password username, password, new_password
|
77
|
+
def update_password username, password, new_password, account: Conjur.configuration.account
|
99
78
|
if Conjur.log
|
100
|
-
Conjur.log << "Updating password for #{username}\n"
|
79
|
+
Conjur.log << "Updating password for #{username} in account #{account}\n"
|
101
80
|
end
|
102
|
-
RestClient::Resource.new(Conjur
|
81
|
+
RestClient::Resource.new(Conjur.configuration.authn_url, user: username, password: password)[fully_escape account]['password'].put new_password
|
103
82
|
end
|
104
83
|
|
105
84
|
#@!endgroup
|
106
85
|
|
107
86
|
#@!group Password and API key management
|
108
87
|
|
109
|
-
# Rotate the currently authenticated user
|
110
|
-
# The old API key is no longer valid after calling this method. You must have the
|
111
|
-
# API key or password to perform this operation. This method *does not* affect
|
112
|
-
#
|
113
|
-
# @note If the user does not have a password, the returned API key will be the **only** way to authenticate as
|
114
|
-
# the user. Therefore, you'd best save it.
|
115
|
-
#
|
116
|
-
# @note This feature requires version 4.6 of the Conjur appliance.
|
88
|
+
# Rotate the currently authenticated user or host API key by generating and returning a new one.
|
89
|
+
# The old API key is no longer valid after calling this method. You must have the current
|
90
|
+
# API key or password to perform this operation. This method *does not* affect a user's password.
|
117
91
|
#
|
118
|
-
# @param [String] username the name of the user whose
|
119
|
-
# @param [String] password the user's current
|
120
|
-
# @
|
121
|
-
|
92
|
+
# @param [String] username the name of the user or host whose API key we want to change
|
93
|
+
# @param [String] password the user's current api key
|
94
|
+
# @param [String] account The organization account.
|
95
|
+
# @return [String] the new API key
|
96
|
+
def rotate_api_key username, password, account: Conjur.configuration.account
|
122
97
|
if Conjur.log
|
123
|
-
Conjur.log << "Rotating API key for self (#{username})\n"
|
98
|
+
Conjur.log << "Rotating API key for self (#{username} in account #{account})\n"
|
124
99
|
end
|
125
100
|
|
126
101
|
RestClient::Resource.new(
|
127
|
-
Conjur
|
102
|
+
Conjur.configuration.authn_url,
|
128
103
|
user: username,
|
129
104
|
password: password
|
130
|
-
)['
|
105
|
+
)[fully_escape account]['api_key'].put('').body
|
131
106
|
end
|
132
107
|
|
133
108
|
#@!endgroup
|
134
109
|
end
|
135
|
-
|
136
|
-
# @api private
|
137
|
-
# This is used internally to create a user that we can log in as without creating
|
138
|
-
# an actual user in the directory, as with #create_user.
|
139
|
-
def create_authn_user login, options = {}
|
140
|
-
log do |logger|
|
141
|
-
logger << "Creating authn user #{login}"
|
142
|
-
end
|
143
|
-
JSON.parse RestClient::Resource.new(Conjur::Authn::API.host, credentials)['users'].post(options.merge(login: login))
|
144
|
-
end
|
145
110
|
end
|
146
111
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright
|
2
|
+
# Copyright 2013-2017 Conjur Inc
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
5
5
|
# this software and associated documentation files (the "Software"), to deal in
|
@@ -22,72 +22,52 @@ require 'conjur/host_factory'
|
|
22
22
|
|
23
23
|
module Conjur
|
24
24
|
class API
|
25
|
+
#@!group Host Factory
|
26
|
+
|
25
27
|
class << self
|
26
|
-
#
|
28
|
+
# Use a host factory token to create a new host. Unlike most other methods, this
|
29
|
+
# method does not require a Conjur access token. The host factory token is the
|
30
|
+
# authentication and authorization to create the host.
|
31
|
+
#
|
32
|
+
# The token must be valid. The host id can be a new host, or an existing host.
|
33
|
+
# If the host already exists, the server verifies that its layer memberships
|
34
|
+
# match the host factory exactly. Then, its API key is rotated and returned with
|
35
|
+
# the response.
|
36
|
+
#
|
37
|
+
# @param [String] token the host factory token.
|
38
|
+
# @param [String] id the id of a new or existing host.
|
39
|
+
# @param options [Hash] additional host creation options.
|
40
|
+
# @return [Host]
|
27
41
|
def host_factory_create_host token, id, options = {}
|
28
42
|
token = token.token if token.is_a?(HostFactoryToken)
|
29
43
|
http_options = {
|
30
44
|
headers: { authorization: %Q(Token token="#{token}") }
|
31
45
|
}
|
32
|
-
response = RestClient::Resource.new(Conjur
|
33
|
-
JSON.parse(response)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
# Options:
|
38
|
-
# +layers+ list of host factory layers
|
39
|
-
# +roleid+ host factory role id
|
40
|
-
# +role+ host factory role. If this is provided, it is converted to roleid.
|
41
|
-
def create_host_factory(id, options = {})
|
42
|
-
if options[:layers]
|
43
|
-
options[:layers] = options[:layers].map do |layer|
|
44
|
-
if layer.is_a?(Conjur::Layer)
|
45
|
-
layer.id
|
46
|
-
elsif layer.is_a?(String)
|
47
|
-
layer
|
48
|
-
else
|
49
|
-
raise "Can't interpret layer #{layer}"
|
50
|
-
end
|
46
|
+
response = RestClient::Resource.new(Conjur.configuration.core_url, http_options)["host_factories"]["hosts"].post(options.merge(id: id)).body
|
47
|
+
attributes = JSON.parse(response)
|
48
|
+
Host.new(attributes['id'], {}).tap do |host|
|
49
|
+
host.attributes = attributes
|
51
50
|
end
|
52
51
|
end
|
53
|
-
|
54
|
-
|
52
|
+
|
53
|
+
# Revokes a host factory token. After revocation, the token can no longer be used to
|
54
|
+
# create hosts.
|
55
|
+
#
|
56
|
+
# @param [Hash] credentials authentication credentials of the current user.
|
57
|
+
# @param [String] token the host factory token.
|
58
|
+
def revoke_host_factory_token credentials, token
|
59
|
+
RestClient::Resource.new(Conjur.configuration.core_url, credentials)['host_factory_tokens'][token].delete
|
55
60
|
end
|
56
|
-
log do |logger|
|
57
|
-
logger << "Creating host_factory #{id}"
|
58
|
-
unless options.blank?
|
59
|
-
logger << " with options #{options.to_json}"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
options ||= {}
|
63
|
-
options[:id] = id
|
64
|
-
resp = RestClient::Resource.new(Conjur::API.host_factory_asset_host, credentials).post(options)
|
65
|
-
Conjur::HostFactory.build_from_response(resp, credentials)
|
66
61
|
end
|
67
62
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
63
|
+
# Revokes a host factory token. After revocation, the token can no longer be used to
|
64
|
+
# create hosts.
|
65
|
+
#
|
66
|
+
# @param [String] token the host factory token.
|
72
67
|
def revoke_host_factory_token token
|
73
|
-
|
74
|
-
RestClient::Resource.new(Conjur::API.host_factory_asset_host, credentials)["tokens/#{token}"].delete
|
75
|
-
end
|
76
|
-
|
77
|
-
def show_host_factory_token token
|
78
|
-
token = token.token if token.is_a?(Conjur::HostFactoryToken)
|
79
|
-
attrs = JSON.parse(RestClient::Resource.new(Conjur::API.host_factory_asset_host, credentials)["tokens/#{token}"].get.body)
|
80
|
-
Conjur::HostFactoryToken.new(Conjur::API.host_factory_asset_host, credentials)["tokens"][attrs['token']].tap do |token|
|
81
|
-
token.attributes = attrs
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
# Creates a Host and returns a Host object.
|
86
|
-
def host_factory_create_host token, id, options = {}
|
87
|
-
attributes = self.class.host_factory_create_host token, id, options
|
88
|
-
Conjur::Host.new(Conjur::API.core_asset_host, credentials)["hosts"][fully_escape attributes['id']].tap do |host|
|
89
|
-
host.attributes = attributes
|
90
|
-
end
|
68
|
+
self.class.revoke_host_factory_token credentials, token
|
91
69
|
end
|
70
|
+
|
71
|
+
#@!endgroup
|
92
72
|
end
|
93
73
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2013-2017 Conjur Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
5
|
+
# this software and associated documentation files (the "Software"), to deal in
|
6
|
+
# the Software without restriction, including without limitation the rights to
|
7
|
+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
8
|
+
# the Software, and to permit persons to whom the Software is furnished to do so,
|
9
|
+
# subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in all
|
12
|
+
# copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
16
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
17
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
18
|
+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
19
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
#
|
21
|
+
require 'conjur/policy_load_result'
|
22
|
+
require 'conjur/policy'
|
23
|
+
|
24
|
+
module Conjur
|
25
|
+
class API
|
26
|
+
#@!group Policy management
|
27
|
+
|
28
|
+
# Append only.
|
29
|
+
POLICY_METHOD_POST = :post
|
30
|
+
# Allow explicit deletion statements, but don't delete implicitly delete data.
|
31
|
+
POLICY_METHOD_PATCH = :patch
|
32
|
+
# Replace the policy entirely, deleting any existing data that is not declared in the new policy.
|
33
|
+
POLICY_METHOD_PUT = :put
|
34
|
+
|
35
|
+
# Load a policy document into the server.
|
36
|
+
#
|
37
|
+
# The modes are support for policy loading:
|
38
|
+
#
|
39
|
+
# * POLICY_METHOD_POST Policy data will be added to the named policy. Deletions are not allowed.
|
40
|
+
# * POLICY_METHOD_PATCH Policy data can be added to or deleted from the named policy. Deletions
|
41
|
+
# are performed by an explicit `!delete` statement.
|
42
|
+
# * POLICY_METHOD_PUT The policy completely replaces the name policy. Policy data which is present
|
43
|
+
# in the server, but not present in the new policy definition, is deleted.
|
44
|
+
#
|
45
|
+
# @param id [String] id of the policy to load.
|
46
|
+
# @param policy [String] YAML-formatted policy definition.
|
47
|
+
# @param account [String] Conjur organization account
|
48
|
+
# @param method [Symbol] Policy load method to use: {POLICY_METHOD_POST} (default), {POLICY_METHOD_PATCH}, or {POLICY_METHOD_PUT}.
|
49
|
+
def load_policy id, policy, account: Conjur.configuration.account, method: POLICY_METHOD_POST
|
50
|
+
request = RestClient::Resource.new(Conjur.configuration.core_url, credentials)['policies'][path_escape account]['policy'][path_escape id]
|
51
|
+
PolicyLoadResult.new JSON.parse(request.send(method, policy))
|
52
|
+
end
|
53
|
+
|
54
|
+
#@!endgroup
|
55
|
+
end
|
56
|
+
end
|
data/lib/conjur/api/pubkeys.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright
|
2
|
+
# Copyright 2013-2017 Conjur Inc
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
5
5
|
# this software and associated documentation files (the "Software"), to deal in
|
@@ -21,165 +21,41 @@
|
|
21
21
|
|
22
22
|
module Conjur
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
# rescue RestClient::ResourceNotFound
|
60
|
-
# puts "Key or user not found!"
|
61
|
-
# # Deal with it
|
62
|
-
# end
|
63
|
-
#
|
64
|
-
#
|
65
|
-
# @param [String] username A Conjur username
|
66
|
-
# @param [String] keyname The name or identifier of the key
|
67
|
-
# @return [String] the public key
|
68
|
-
# @raise [RestClient::ResourceNotFound] if the user or key does not exist.
|
69
|
-
def public_key username, keyname
|
70
|
-
public_keys_resource(username, keyname).get
|
71
|
-
end
|
72
|
-
|
73
|
-
# List the public key names for the given user.
|
74
|
-
#
|
75
|
-
# If the given user does not exist, an empty Array will be returned. This is to prevent attackers from determining whether
|
76
|
-
# a user exists.
|
77
|
-
#
|
78
|
-
# ## Permissions
|
79
|
-
# You do not need any special permissions to call this method, since public keys are, well, public.
|
80
|
-
#
|
81
|
-
#
|
82
|
-
# @example List the names of public keys for 'otto'
|
83
|
-
# api.public_key_names('otto').each{|n| puts n}
|
84
|
-
# # otto@somehost
|
85
|
-
# # admin@someotherhost
|
86
|
-
#
|
87
|
-
# @example A non existent user has no public keys
|
88
|
-
# user = api.user('doesnotexist')
|
89
|
-
# user.exists? # => false
|
90
|
-
# user.public_key_names # => []
|
91
|
-
#
|
92
|
-
# @param [String] username the Conjur username
|
93
|
-
# @return [Array<String>] the names of the user's public keys
|
94
|
-
def public_key_names username
|
95
|
-
public_keys(username).lines.map{|s| s.split(' ')[-1]}
|
96
|
-
end
|
97
|
-
|
98
|
-
# Add an SSH public key for `username`.
|
99
|
-
#
|
100
|
-
# ## Key Format
|
101
|
-
#
|
102
|
-
# This method will raise an exception if `key` is not of the format
|
103
|
-
# `"<algorithm> <data> <name>"` (that is, key.split(\s+\)).length must be 3). The `<name>` field is used by the service
|
104
|
-
# to identify individual keys for a user.
|
105
|
-
#
|
106
|
-
# ## Permissions
|
107
|
-
#
|
108
|
-
# You must have permission to `'update'` the pubkeys service resource. When the Conjur appliance
|
109
|
-
# is configured, it creates the pubkeys service resource with this identifier
|
110
|
-
# `'<organizational account>:service:pubkeys-1.0/public-keys'`.
|
111
|
-
#
|
112
|
-
# Rather than granting permissions to this resource directly to user roles, we recommend that you add them to the
|
113
|
-
# 'key-managers' group, whose *unqualified identifier* is 'pubkeys-1.0/key-managers', which has permission to add public
|
114
|
-
# keys.
|
115
|
-
#
|
116
|
-
# ## Hiding Existence
|
117
|
-
#
|
118
|
-
# Because attackers could use this method to determine the existence of Conjur users, it will not
|
119
|
-
# raise an error if the user does not exist.
|
120
|
-
#
|
121
|
-
# @example add a user's public key
|
122
|
-
# # Check that the user exists so that we can fail when he doesn't. Otherwise, this method
|
123
|
-
# # will silently fail.
|
124
|
-
# raise "No such user!" unless api.user('bob').exists?
|
125
|
-
#
|
126
|
-
# # Add a key from a file
|
127
|
-
# key = File.read('/path/to/public/key.pub')
|
128
|
-
# api.add_public_key('bob', key)
|
129
|
-
#
|
130
|
-
# @param [String] username the name of the Conjur
|
131
|
-
# @param [String] key an SSH formated public key
|
132
|
-
# @return void
|
133
|
-
# @raise RestClient::BadRequest when the key is not in the correct format.
|
134
|
-
def add_public_key username, key
|
135
|
-
public_keys_resource(username).post key
|
136
|
-
end
|
137
|
-
|
138
|
-
# Delete a specific public key for a user.
|
139
|
-
#
|
140
|
-
# ## Permissions
|
141
|
-
# You must have permission to `'update'` the pubkeys service resource. When the Conjur appliance
|
142
|
-
# is configured, it creates the pubkeys service resource with this identifier
|
143
|
-
# `'<organizational account>:service:pubkeys-1.0/public-keys'`.
|
144
|
-
#
|
145
|
-
# Rather than granting permissions to this resource directly to user roles, we recommend that you add them to the
|
146
|
-
# 'key-managers' group, whose *unqualified identifier* is 'pubkeys-1.0/key-managers', which has permission to add public
|
147
|
-
# keys.
|
148
|
-
#
|
149
|
-
# ## Hiding Existence
|
150
|
-
#
|
151
|
-
# Because attackers could use this method to determine the existence of Conjur users, it will not
|
152
|
-
# raise an error if the user does not exist.
|
153
|
-
#
|
154
|
-
# @example Delete all public keys for 'bob'
|
155
|
-
#
|
156
|
-
# api.public_key_names('bob').count # => 6
|
157
|
-
# api.public_key_names('bob').each do |keyname|
|
158
|
-
# api.delete_public_key 'bob', keyname
|
159
|
-
# end
|
160
|
-
# api.public_key_names('bob').count # => 0
|
161
|
-
#
|
162
|
-
#
|
163
|
-
# @param [String] username the Conjur username/login
|
164
|
-
# @param [String] keyname the individual key to delete.
|
165
|
-
# @return [void]
|
166
|
-
def delete_public_key username, keyname
|
167
|
-
public_keys_resource(username, keyname).delete
|
168
|
-
end
|
169
|
-
|
170
|
-
#@!endgroup
|
171
|
-
|
172
|
-
protected
|
173
|
-
# @api private
|
174
|
-
# Returns a RestClient::Resource with the pubkeys host and the given path.
|
175
|
-
def public_keys_resource *path
|
176
|
-
RestClient::Resource.new(Conjur::API.pubkeys_asset_host, credentials)[public_keys_path *path]
|
177
|
-
end
|
178
|
-
|
179
|
-
# @api private
|
180
|
-
# This method simply escapes each segment in `args` and joins them around `/`.
|
181
|
-
def public_keys_path *args
|
182
|
-
args.map{|a| fully_escape(a)}.join('/')
|
24
|
+
class API
|
25
|
+
class << self
|
26
|
+
# @!group Public Keys
|
27
|
+
|
28
|
+
# Fetch *all* public keys for the user. This method returns a newline delimited
|
29
|
+
# String for compatibility with the authorized_keys SSH format.
|
30
|
+
#
|
31
|
+
#
|
32
|
+
# If the given user does not exist, an empty String will be returned. This is to prevent attackers from determining whether
|
33
|
+
# a user exists.
|
34
|
+
#
|
35
|
+
# ## Permissions
|
36
|
+
# You do not need any special permissions to call this method, since public keys are, well, public.
|
37
|
+
#
|
38
|
+
#
|
39
|
+
# @example
|
40
|
+
# puts api.public_keys('jon')
|
41
|
+
# # ssh-rsa [big long string] jon@albert
|
42
|
+
# # ssh-rsa [big long string] jon@conjurops
|
43
|
+
#
|
44
|
+
# @param [String] username the *unqualified* Conjur username
|
45
|
+
# @return [String] newline delimited public keys
|
46
|
+
def public_keys username, account: Conjur.configuration.account
|
47
|
+
public_keys_resource(username, account).get
|
48
|
+
end
|
49
|
+
|
50
|
+
#@!endgroup
|
51
|
+
|
52
|
+
protected
|
53
|
+
|
54
|
+
# @api private
|
55
|
+
# Returns a RestClient::Resource with the pubkeys host and the given path.
|
56
|
+
def public_keys_resource username, account
|
57
|
+
RestClient::Resource.new(Conjur.configuration.core_url)['public_keys'][fully_escape account]['user'][path_escape username]
|
58
|
+
end
|
183
59
|
end
|
184
60
|
end
|
185
61
|
end
|