conjur-api 5.3.2 → 5.3.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +10 -0
- data/.gitleaks.toml +1 -1
- data/CHANGELOG.md +41 -1
- data/CONTRIBUTING.md +15 -23
- data/Dockerfile +2 -1
- data/Gemfile +1 -5
- data/Jenkinsfile +79 -35
- data/LICENSE +1 -1
- data/README.md +35 -2
- data/SECURITY.md +42 -0
- data/ci/submit-coverage +36 -0
- data/conjur-api.gemspec +5 -4
- data/docker-compose.yml +15 -3
- data/features/host.feature +39 -9
- data/features/step_definitions/api_steps.rb +14 -3
- data/features/step_definitions/policy_steps.rb +40 -0
- data/features/support/env.rb +3 -3
- data/features/user.feature +47 -6
- data/features_v4/support/env.rb +0 -2
- data/lib/conjur/acts_as_user.rb +5 -1
- data/lib/conjur/api/authn.rb +3 -3
- data/lib/conjur/api/resources.rb +2 -2
- data/lib/conjur/api/router/v4.rb +80 -23
- data/lib/conjur/api/router/v5.rb +87 -21
- data/lib/conjur/api.rb +0 -18
- data/lib/conjur/base.rb +19 -5
- data/lib/conjur/base_object.rb +14 -7
- data/lib/conjur/configuration.rb +45 -17
- data/lib/conjur/escape.rb +2 -3
- data/lib/conjur-api/version.rb +2 -2
- data/spec/api_spec.rb +59 -13
- data/spec/base_object_spec.rb +0 -1
- data/spec/configuration_spec.rb +25 -3
- data/spec/spec_helper.rb +4 -4
- data/spec/ssl_spec.rb +50 -26
- data/test.sh +10 -14
- metadata +35 -21
- data/.github/ISSUE_TEMPLATE/bug.md +0 -27
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -27
- data/bin/release +0 -43
- data/ci/codeclimate.dockerfile +0 -6
- data/spec/vendor/rest_client_spec.rb +0 -41
data/features/user.feature
CHANGED
@@ -1,17 +1,58 @@
|
|
1
|
-
Feature:
|
1
|
+
Feature: User object
|
2
2
|
|
3
3
|
Background:
|
4
|
-
Given a new user
|
5
4
|
|
6
|
-
Scenario: User has a uidnumber
|
7
|
-
|
5
|
+
Scenario: User has a uidnumber
|
6
|
+
Given a new user
|
7
|
+
Then I can run the code:
|
8
8
|
"""
|
9
9
|
@user.uidnumber
|
10
10
|
"""
|
11
11
|
Then the result should be "1000"
|
12
12
|
|
13
|
-
Scenario: Logged-in user is the current_role
|
14
|
-
|
13
|
+
Scenario: Logged-in user is the current_role
|
14
|
+
Given a new user
|
15
|
+
Then I can run the code:
|
15
16
|
"""
|
16
17
|
expect($conjur.current_role(Conjur.configuration.account).id.to_s).to eq("cucumber:user:admin")
|
17
18
|
"""
|
19
|
+
|
20
|
+
# Rotation of own API key should be done via `Conjur::API.rotate_api_key()`
|
21
|
+
Scenario: User's own API key cannot be rotated with an API key
|
22
|
+
Given a new user
|
23
|
+
Then this code should fail with "You cannot rotate your own API key via this method"
|
24
|
+
"""
|
25
|
+
user = Conjur::API.new_from_key(@user.login, @user_api_key).resource(@user.id)
|
26
|
+
user.rotate_api_key
|
27
|
+
"""
|
28
|
+
|
29
|
+
# Rotation of own API key should be done via `Conjur::API.rotate_api_key()`
|
30
|
+
Scenario: User's own API key cannot be rotated with a token
|
31
|
+
Given a new user
|
32
|
+
Then this code should fail with "You cannot rotate your own API key via this method"
|
33
|
+
"""
|
34
|
+
token = Conjur::API.new_from_key(@user.login, @user_api_key).token
|
35
|
+
|
36
|
+
user = Conjur::API.new_from_token(token).resource(@user.id)
|
37
|
+
user.rotate_api_key
|
38
|
+
"""
|
39
|
+
|
40
|
+
Scenario: Delegated user's API key can be rotated with an API key
|
41
|
+
Given a new delegated user
|
42
|
+
Then I can run the code:
|
43
|
+
"""
|
44
|
+
delegated_user_resource = Conjur::API.new_from_key(@user_owner.login, @user_owner_api_key).resource(@user.id)
|
45
|
+
api_key = delegated_user_resource.rotate_api_key
|
46
|
+
Conjur::API.new_from_key(delegated_user_resource.login, api_key).token
|
47
|
+
"""
|
48
|
+
|
49
|
+
Scenario: Delegated user's API key can be rotated with a token
|
50
|
+
Given a new delegated user
|
51
|
+
Then I can run the code:
|
52
|
+
"""
|
53
|
+
token = Conjur::API.new_from_key(@user_owner.login, @user_owner_api_key).token
|
54
|
+
|
55
|
+
delegated_user_resource = Conjur::API.new_from_token(token).resource(@user.id)
|
56
|
+
api_key = delegated_user_resource.rotate_api_key
|
57
|
+
Conjur::API.new_from_key(delegated_user_resource.login, api_key).token
|
58
|
+
"""
|
data/features_v4/support/env.rb
CHANGED
data/lib/conjur/acts_as_user.rb
CHANGED
@@ -52,12 +52,16 @@ module Conjur
|
|
52
52
|
# @note You will not be able to access the API key returned by this method later, so you should
|
53
53
|
# probably hang onto it it.
|
54
54
|
#
|
55
|
-
# @note You cannot rotate your own API key with this method. To do so, use `Conjur::API.rotate_api_key
|
55
|
+
# @note You cannot rotate your own API key with this method. To do so, use `Conjur::API.rotate_api_key`.
|
56
56
|
#
|
57
57
|
# @note This feature requires a Conjur appliance running version 4.6 or higher.
|
58
58
|
#
|
59
59
|
# @return [String] the new API key for this user.
|
60
60
|
def rotate_api_key
|
61
|
+
if login == username
|
62
|
+
raise 'You cannot rotate your own API key via this method. To do so, use `Conjur::API.rotate_api_key`'
|
63
|
+
end
|
64
|
+
|
61
65
|
url_for(:authn_rotate_api_key, credentials, account, id).put("").body
|
62
66
|
end
|
63
67
|
end
|
data/lib/conjur/api/authn.rb
CHANGED
@@ -50,7 +50,7 @@ module Conjur
|
|
50
50
|
url_for(:authn_login, account, username, password).get
|
51
51
|
end
|
52
52
|
|
53
|
-
# Exchanges Conjur the API key (refresh token) for an access token. The access token can
|
53
|
+
# Exchanges Conjur the API key (refresh token) for an access token. The access token can
|
54
54
|
# then be used to authenticate further API calls.
|
55
55
|
#
|
56
56
|
# @param [String] username The username or host id for which we want a token
|
@@ -65,7 +65,7 @@ module Conjur
|
|
65
65
|
JSON.parse url_for(:authn_authenticate, account, username).post(api_key, content_type: 'text/plain')
|
66
66
|
end
|
67
67
|
|
68
|
-
# Obtains an access token from the +authn_local+ service. The access token can
|
68
|
+
# Obtains an access token from the +authn_local+ service. The access token can
|
69
69
|
# then be used to authenticate further API calls.
|
70
70
|
#
|
71
71
|
# @param [String] username The username or host id for which we want a token
|
@@ -80,7 +80,7 @@ module Conjur
|
|
80
80
|
require 'json'
|
81
81
|
require 'socket'
|
82
82
|
message = url_for(:authn_authenticate_local, username, account, expiration, cidr)
|
83
|
-
JSON.parse(UNIXSocket.open(Conjur.configuration.authn_local_socket) {|s| s.puts message; s.gets })
|
83
|
+
JSON.parse(UNIXSocket.open(Conjur.configuration.authn_local_socket) {|s| s.puts message; s.gets })
|
84
84
|
end
|
85
85
|
|
86
86
|
# Change a user's password. To do this, you must have the user's current password. This does not change or rotate
|
data/lib/conjur/api/resources.rb
CHANGED
@@ -20,7 +20,7 @@ module Conjur
|
|
20
20
|
class API
|
21
21
|
include QueryString
|
22
22
|
include BuildObject
|
23
|
-
|
23
|
+
|
24
24
|
#@!group Resources
|
25
25
|
|
26
26
|
# Find a resource by its id.
|
@@ -84,7 +84,7 @@ module Conjur
|
|
84
84
|
def resources options = {}
|
85
85
|
options = { host: Conjur.configuration.core_url, credentials: credentials }.merge options
|
86
86
|
options[:account] ||= Conjur.configuration.account
|
87
|
-
|
87
|
+
|
88
88
|
host, credentials, account, kind = options.values_at(*[:host, :credentials, :account, :kind])
|
89
89
|
fail ArgumentError, "host and account are required" unless [host, account].all?
|
90
90
|
%w(host credentials account kind).each do |name|
|
data/lib/conjur/api/router/v4.rb
CHANGED
@@ -8,18 +8,27 @@ module Conjur
|
|
8
8
|
|
9
9
|
def authn_login account, username, password
|
10
10
|
verify_account(account)
|
11
|
-
RestClient::Resource.new(
|
11
|
+
RestClient::Resource.new(
|
12
|
+
Conjur.configuration.authn_url,
|
13
|
+
Conjur.configuration.create_rest_client_options(
|
14
|
+
user: username,
|
15
|
+
password: password
|
16
|
+
)
|
17
|
+
)['users/login']
|
12
18
|
end
|
13
19
|
|
14
20
|
def authn_authenticate account, username
|
15
21
|
verify_account(account)
|
16
|
-
RestClient::Resource.new(
|
22
|
+
RestClient::Resource.new(
|
23
|
+
Conjur.configuration.authn_url,
|
24
|
+
Conjur.configuration.rest_client_options
|
25
|
+
)['users'][fully_escape username]['authenticate']
|
17
26
|
end
|
18
27
|
|
19
28
|
# For v4, the authn-local message is the username.
|
20
29
|
def authn_authenticate_local username, account, expiration, cidr, &block
|
21
30
|
verify_account(account)
|
22
|
-
|
31
|
+
|
23
32
|
raise "'expiration' is not supported for authn-local v4" if expiration
|
24
33
|
raise "'cidr' is not supported for authn-local v4" if cidr
|
25
34
|
|
@@ -28,36 +37,51 @@ module Conjur
|
|
28
37
|
|
29
38
|
def authn_rotate_api_key credentials, account, id
|
30
39
|
verify_account(account)
|
31
|
-
username =
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
RestClient::Resource.new(Conjur.configuration.authn_url, credentials)['users']["api_key?id=#{username}"]
|
40
|
+
username = id.kind == "user" ? id.identifier : [id.kind, id.identifier].join('/')
|
41
|
+
RestClient::Resource.new(
|
42
|
+
Conjur.configuration.authn_url,
|
43
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
44
|
+
)['users']["api_key?id=#{username}"]
|
37
45
|
end
|
38
46
|
|
39
47
|
def authn_rotate_own_api_key account, username, password
|
40
48
|
verify_account(account)
|
41
|
-
RestClient::Resource.new(
|
49
|
+
RestClient::Resource.new(
|
50
|
+
Conjur.configuration.authn_url,
|
51
|
+
Conjur.configuration.create_rest_client_options(user: username, password: password)
|
52
|
+
)['users']["api_key"]
|
42
53
|
end
|
43
54
|
|
44
55
|
def host_factory_create_host token
|
45
56
|
http_options = {
|
46
57
|
headers: { authorization: %Q(Token token="#{token}") }
|
47
58
|
}
|
48
|
-
RestClient::Resource.new(
|
59
|
+
RestClient::Resource.new(
|
60
|
+
Conjur.configuration.core_url,
|
61
|
+
Conjur.configuration.create_rest_client_options(http_options)
|
62
|
+
)['host_factories']['hosts']
|
49
63
|
end
|
50
64
|
|
51
65
|
def host_factory_create_tokens credentials, id
|
52
|
-
RestClient::Resource.new(
|
66
|
+
RestClient::Resource.new(
|
67
|
+
Conjur.configuration.core_url,
|
68
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
69
|
+
)['host_factories'][id.identifier]['tokens']
|
53
70
|
end
|
54
71
|
|
55
72
|
def host_factory_revoke_token credentials, token
|
56
|
-
RestClient::Resource.new(
|
73
|
+
RestClient::Resource.new(
|
74
|
+
Conjur.configuration.core_url,
|
75
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
76
|
+
)['host_factories']['tokens'][token]
|
57
77
|
end
|
58
78
|
|
59
79
|
def resources_resource credentials, id
|
60
|
-
|
80
|
+
|
81
|
+
RestClient::Resource.new(
|
82
|
+
Conjur.configuration.core_url,
|
83
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
84
|
+
)['authz'][id.account]['resources'][id.kind][id.identifier]
|
61
85
|
end
|
62
86
|
|
63
87
|
def resources_check credentials, id, privilege, role
|
@@ -73,47 +97,80 @@ module Conjur
|
|
73
97
|
end
|
74
98
|
|
75
99
|
def resources_permitted_roles credentials, id, privilege
|
76
|
-
RestClient::Resource.new(
|
100
|
+
RestClient::Resource.new(
|
101
|
+
Conjur.configuration.core_url,
|
102
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
103
|
+
)['authz'][id.account]['roles']['allowed_to'][privilege][id.kind][id.identifier]
|
77
104
|
end
|
78
105
|
|
79
106
|
def roles_role credentials, id
|
80
|
-
RestClient::Resource.new(
|
107
|
+
RestClient::Resource.new(
|
108
|
+
Conjur.configuration.core_url,
|
109
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
110
|
+
)['authz'][id.account]['roles'][id.kind][id.identifier]
|
81
111
|
end
|
82
112
|
|
83
113
|
def secrets_add credentials, id
|
84
114
|
verify_account(id.account)
|
85
|
-
RestClient::Resource.new(
|
115
|
+
RestClient::Resource.new(
|
116
|
+
Conjur.configuration.core_url,
|
117
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
118
|
+
)['variables'][fully_escape id.identifier]['values']
|
86
119
|
end
|
87
120
|
|
88
121
|
def variable credentials, id
|
89
122
|
verify_account(id.account)
|
90
|
-
RestClient::Resource.new(
|
123
|
+
RestClient::Resource.new(
|
124
|
+
Conjur.configuration.core_url,
|
125
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
126
|
+
)['variables'][fully_escape id.identifier]
|
91
127
|
end
|
92
128
|
|
93
129
|
def secrets_value credentials, id, options
|
94
|
-
RestClient::Resource.new(
|
130
|
+
RestClient::Resource.new(
|
131
|
+
Conjur.configuration.core_url,
|
132
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
133
|
+
)['variables'][fully_escape id.identifier]['value'][options_querystring options]
|
95
134
|
end
|
96
135
|
|
97
136
|
def secrets_values credentials, variable_ids
|
98
137
|
options = {
|
99
138
|
vars: Array(variable_ids).map { |v| fully_escape(v.identifier) }.join(',')
|
100
139
|
}
|
101
|
-
RestClient::Resource.new(
|
140
|
+
RestClient::Resource.new(
|
141
|
+
Conjur.configuration.core_url,
|
142
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
143
|
+
)['variables']['values'][options_querystring options]
|
102
144
|
end
|
103
145
|
|
104
146
|
def group_attributes credentials, resource, id
|
105
147
|
verify_account(id.account)
|
106
|
-
JSON.parse(
|
148
|
+
JSON.parse(
|
149
|
+
RestClient::Resource.new(
|
150
|
+
Conjur.configuration.core_url,
|
151
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
152
|
+
)['groups'][fully_escape id.identifier].get
|
153
|
+
)
|
107
154
|
end
|
108
155
|
|
109
156
|
def variable_attributes credentials, resource, id
|
110
157
|
verify_account(id.account)
|
111
|
-
JSON.parse(
|
158
|
+
JSON.parse(
|
159
|
+
RestClient::Resource.new(
|
160
|
+
Conjur.configuration.core_url,
|
161
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
162
|
+
)['variables'][fully_escape id.identifier].get
|
163
|
+
)
|
112
164
|
end
|
113
165
|
|
114
166
|
def user_attributes credentials, resource, id
|
115
167
|
verify_account(id.account)
|
116
|
-
JSON.parse(
|
168
|
+
JSON.parse(
|
169
|
+
RestClient::Resource.new(
|
170
|
+
Conjur.configuration.core_url,
|
171
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
172
|
+
)['users'][fully_escape id.identifier].get
|
173
|
+
)
|
117
174
|
end
|
118
175
|
|
119
176
|
def parse_group_gidnumber attributes
|
data/lib/conjur/api/router/v5.rb
CHANGED
@@ -27,19 +27,34 @@ module Conjur
|
|
27
27
|
extend self
|
28
28
|
|
29
29
|
def authn_login account, username, password
|
30
|
-
RestClient::Resource.new(
|
30
|
+
RestClient::Resource.new(
|
31
|
+
Conjur.configuration.authn_url,
|
32
|
+
Conjur.configuration.create_rest_client_options(
|
33
|
+
user: username,
|
34
|
+
password: password
|
35
|
+
)
|
36
|
+
)[fully_escape account]['login']
|
31
37
|
end
|
32
38
|
|
33
39
|
def authn_authenticate account, username
|
34
|
-
RestClient::Resource.new(
|
40
|
+
RestClient::Resource.new(
|
41
|
+
Conjur.configuration.authn_url,
|
42
|
+
Conjur.configuration.rest_client_options
|
43
|
+
)[fully_escape account][fully_escape username]['authenticate']
|
35
44
|
end
|
36
45
|
|
37
46
|
def authenticator account, authenticator, service_id, credentials
|
38
|
-
RestClient::Resource.new(
|
47
|
+
RestClient::Resource.new(
|
48
|
+
Conjur.configuration.core_url,
|
49
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
50
|
+
)[fully_escape authenticator][fully_escape service_id][fully_escape account]
|
39
51
|
end
|
40
52
|
|
41
53
|
def authenticators
|
42
|
-
RestClient::Resource.new(
|
54
|
+
RestClient::Resource.new(
|
55
|
+
Conjur.configuration.core_url,
|
56
|
+
Conjur.configuration.rest_client_options
|
57
|
+
)['authenticators']
|
43
58
|
end
|
44
59
|
|
45
60
|
# For v5, the authn-local message is a JSON string with account, sub, and optional fields.
|
@@ -51,38 +66,68 @@ module Conjur
|
|
51
66
|
end
|
52
67
|
|
53
68
|
def authn_update_password account, username, password
|
54
|
-
RestClient::Resource.new(
|
69
|
+
RestClient::Resource.new(
|
70
|
+
Conjur.configuration.authn_url,
|
71
|
+
Conjur.configuration.create_rest_client_options(
|
72
|
+
user: username,
|
73
|
+
password: password
|
74
|
+
)
|
75
|
+
)[fully_escape account]['password']
|
55
76
|
end
|
56
77
|
|
57
78
|
def authn_rotate_api_key credentials, account, id
|
58
|
-
RestClient::Resource.new(
|
79
|
+
RestClient::Resource.new(
|
80
|
+
Conjur.configuration.core_url,
|
81
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
82
|
+
)['authn'][fully_escape account]["api_key?role=#{id}"]
|
59
83
|
end
|
60
84
|
|
61
85
|
def authn_rotate_own_api_key account, username, password
|
62
|
-
RestClient::Resource.new(
|
86
|
+
RestClient::Resource.new(
|
87
|
+
Conjur.configuration.authn_url,
|
88
|
+
Conjur.configuration.create_rest_client_options(
|
89
|
+
user: username,
|
90
|
+
password: password
|
91
|
+
)
|
92
|
+
)[fully_escape account]['api_key']
|
63
93
|
end
|
64
94
|
|
65
95
|
def host_factory_create_host token
|
66
96
|
http_options = {
|
67
97
|
headers: { authorization: %Q(Token token="#{token}") }
|
68
98
|
}
|
69
|
-
RestClient::Resource.new(
|
99
|
+
RestClient::Resource.new(
|
100
|
+
Conjur.configuration.core_url,
|
101
|
+
Conjur.configuration.create_rest_client_options(http_options)
|
102
|
+
)["host_factories"]["hosts"]
|
70
103
|
end
|
71
104
|
|
72
105
|
def host_factory_create_tokens credentials, id
|
73
|
-
RestClient::Resource.new(
|
106
|
+
RestClient::Resource.new(
|
107
|
+
Conjur.configuration.core_url,
|
108
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
109
|
+
)['host_factory_tokens']
|
74
110
|
end
|
75
111
|
|
76
112
|
def host_factory_revoke_token credentials, token
|
77
|
-
RestClient::Resource.new(
|
113
|
+
RestClient::Resource.new(
|
114
|
+
Conjur.configuration.core_url,
|
115
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
116
|
+
)['host_factory_tokens'][token]
|
78
117
|
end
|
79
118
|
|
80
119
|
def policies_load_policy credentials, account, id
|
81
|
-
RestClient::Resource.new(
|
120
|
+
RestClient::Resource.new(
|
121
|
+
Conjur.configuration.core_url,
|
122
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
123
|
+
)['policies'][fully_escape account]['policy'][fully_escape id]
|
82
124
|
end
|
83
125
|
|
84
126
|
def public_keys_for_user account, username
|
85
|
-
RestClient::Resource.new(
|
127
|
+
RestClient::Resource.new(
|
128
|
+
Conjur.configuration.core_url,
|
129
|
+
Conjur.configuration.rest_client_options
|
130
|
+
)['public_keys'][fully_escape account]['user'][fully_escape username]
|
86
131
|
end
|
87
132
|
|
88
133
|
def resources credentials, account, kind, options
|
@@ -91,11 +136,17 @@ module Conjur
|
|
91
136
|
path = "/resources/#{fully_escape account}"
|
92
137
|
path += "/#{fully_escape kind}" if kind
|
93
138
|
|
94
|
-
RestClient::Resource.new(
|
139
|
+
RestClient::Resource.new(
|
140
|
+
Conjur.configuration.core_url,
|
141
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
142
|
+
)[path][options_querystring options]
|
95
143
|
end
|
96
144
|
|
97
145
|
def resources_resource credentials, id
|
98
|
-
RestClient::Resource.new(
|
146
|
+
RestClient::Resource.new(
|
147
|
+
Conjur.configuration.core_url,
|
148
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
149
|
+
)['resources'][id.to_url_path]
|
99
150
|
end
|
100
151
|
|
101
152
|
def resources_permitted_roles credentials, id, privilege
|
@@ -114,22 +165,34 @@ module Conjur
|
|
114
165
|
end
|
115
166
|
|
116
167
|
def roles_role credentials, id
|
117
|
-
RestClient::Resource.new(
|
168
|
+
RestClient::Resource.new(
|
169
|
+
Conjur.configuration.core_url,
|
170
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
171
|
+
)['roles'][id.to_url_path]
|
118
172
|
end
|
119
173
|
|
120
174
|
def secrets_add credentials, id
|
121
|
-
RestClient::Resource.new(
|
175
|
+
RestClient::Resource.new(
|
176
|
+
Conjur.configuration.core_url,
|
177
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
178
|
+
)['secrets'][id.to_url_path]
|
122
179
|
end
|
123
180
|
|
124
181
|
def secrets_value credentials, id, options
|
125
|
-
RestClient::Resource.new(
|
182
|
+
RestClient::Resource.new(
|
183
|
+
Conjur.configuration.core_url,
|
184
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
185
|
+
)['secrets'][id.to_url_path][options_querystring options]
|
126
186
|
end
|
127
187
|
|
128
188
|
def secrets_values credentials, variable_ids
|
129
189
|
options = {
|
130
190
|
variable_ids: Array(variable_ids).join(',')
|
131
191
|
}
|
132
|
-
RestClient::Resource.new(
|
192
|
+
RestClient::Resource.new(
|
193
|
+
Conjur.configuration.core_url,
|
194
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
195
|
+
)['secrets'][options_querystring(options).gsub("%2C", ',')]
|
133
196
|
end
|
134
197
|
|
135
198
|
def group_attributes credentials, resource, id
|
@@ -167,13 +230,16 @@ module Conjur
|
|
167
230
|
end
|
168
231
|
|
169
232
|
def ldap_sync_policy(credentials, config_name)
|
170
|
-
RestClient::Resource.new(
|
233
|
+
RestClient::Resource.new(
|
234
|
+
Conjur.configuration.core_url,
|
235
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
236
|
+
)['ldap-sync']["policy?config_name=#{fully_escape(config_name)}"]
|
171
237
|
end
|
172
|
-
|
238
|
+
|
173
239
|
private
|
174
240
|
|
175
241
|
def resource_annotations resource
|
176
|
-
resource.attributes['annotations']
|
242
|
+
resource.attributes['annotations']
|
177
243
|
end
|
178
244
|
end
|
179
245
|
end
|
data/lib/conjur/api.rb
CHANGED
@@ -50,24 +50,6 @@ require 'conjur/layer'
|
|
50
50
|
require 'conjur/cache'
|
51
51
|
require 'conjur-api/version'
|
52
52
|
|
53
|
-
# Monkey patch RestClient::Request so it always uses
|
54
|
-
# :ssl_cert_store. (RestClient::Resource uses Request to send
|
55
|
-
# requests, so it sees :ssl_cert_store, too).
|
56
|
-
# @api private
|
57
|
-
class RestClient::Request
|
58
|
-
alias_method :initialize_without_defaults, :initialize
|
59
|
-
|
60
|
-
def default_args
|
61
|
-
{
|
62
|
-
ssl_cert_store: OpenSSL::SSL::SSLContext::DEFAULT_CERT_STORE
|
63
|
-
}
|
64
|
-
end
|
65
|
-
|
66
|
-
def initialize args
|
67
|
-
initialize_without_defaults default_args.merge(args)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
53
|
# @api private
|
72
54
|
class RestClient::Resource
|
73
55
|
include Conjur::Escape
|
data/lib/conjur/base.rb
CHANGED
@@ -123,19 +123,21 @@ module Conjur
|
|
123
123
|
#
|
124
124
|
# @return [String] the api key, or nil if this instance was created from a token.
|
125
125
|
attr_reader :api_key
|
126
|
-
|
126
|
+
|
127
127
|
#@!attribute [r] remote_ip
|
128
128
|
# An optional IP address to be recorded in the audit record for any actions performed by this API instance.
|
129
129
|
attr_reader :remote_ip
|
130
130
|
|
131
131
|
# The name of the user as which this api instance is authenticated. This is available whether the api
|
132
|
-
# instance was created from credentials or an authentication token.
|
132
|
+
# instance was created from credentials or an authentication token. If the instance was created from
|
133
|
+
# credentials, we will use that value directly otherwise we will attempt to extract the username from
|
134
|
+
# the token (either the old-style data field or the new-style JWT `sub` field).
|
133
135
|
#
|
134
136
|
# @return [String] the login of the current user.
|
135
137
|
def username
|
136
|
-
@username || token['data']
|
138
|
+
@username || token['data'] || jwt_username(token)
|
137
139
|
end
|
138
|
-
|
140
|
+
|
139
141
|
# @api private
|
140
142
|
# used to delegate to host providing subclasses.
|
141
143
|
# @return [String] the host
|
@@ -213,7 +215,7 @@ module Conjur
|
|
213
215
|
@account = account
|
214
216
|
@username = username
|
215
217
|
@api_key = api_key
|
216
|
-
|
218
|
+
|
217
219
|
update_token_born
|
218
220
|
end
|
219
221
|
|
@@ -323,6 +325,18 @@ module Conjur
|
|
323
325
|
|
324
326
|
private
|
325
327
|
|
328
|
+
# Tries to get the username (subject) from a JWT API token by examining
|
329
|
+
# its content.
|
330
|
+
#
|
331
|
+
# @return [String] of the 'sub' payload field from the JWT if present,
|
332
|
+
# otherwise return nil
|
333
|
+
def jwt_username raw_token
|
334
|
+
return nil unless raw_token
|
335
|
+
return nil unless raw_token.include? 'payload'
|
336
|
+
|
337
|
+
JSON.parse(Base64.strict_decode64(raw_token["payload"]))["sub"]
|
338
|
+
end
|
339
|
+
|
326
340
|
# Tries to refresh the token if possible.
|
327
341
|
#
|
328
342
|
# @return [Hash, false] false if the token couldn't be refreshed due to
|
data/lib/conjur/base_object.rb
CHANGED
@@ -20,9 +20,9 @@ module Conjur
|
|
20
20
|
include LogSource
|
21
21
|
include BuildObject
|
22
22
|
include Routing
|
23
|
-
|
23
|
+
|
24
24
|
attr_reader :id, :credentials
|
25
|
-
|
25
|
+
|
26
26
|
def initialize id, credentials
|
27
27
|
@id = Id.new id
|
28
28
|
@credentials = credentials
|
@@ -34,10 +34,18 @@ module Conjur
|
|
34
34
|
}
|
35
35
|
end
|
36
36
|
|
37
|
-
def account
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
def account
|
38
|
+
id.account
|
39
|
+
end
|
40
|
+
|
41
|
+
def kind
|
42
|
+
id.kind
|
43
|
+
end
|
44
|
+
|
45
|
+
def identifier
|
46
|
+
id.identifier
|
47
|
+
end
|
48
|
+
|
41
49
|
def username
|
42
50
|
credentials[:username] or raise "No username found in credentials"
|
43
51
|
end
|
@@ -45,6 +53,5 @@ module Conjur
|
|
45
53
|
def inspect
|
46
54
|
"<#{self.class.name} id='#{id.to_s}'>"
|
47
55
|
end
|
48
|
-
|
49
56
|
end
|
50
57
|
end
|