conjur-api 5.3.8.pre.319 → 5.3.8.pre.321

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +10 -0
  3. data/.dockerignore +1 -0
  4. data/.github/CODEOWNERS +10 -0
  5. data/.gitignore +32 -0
  6. data/.gitleaks.toml +219 -0
  7. data/.overcommit.yml +16 -0
  8. data/.project +18 -0
  9. data/.rubocop.yml +3 -0
  10. data/.rubocop_settings.yml +86 -0
  11. data/.rubocop_todo.yml +709 -0
  12. data/.yardopts +1 -0
  13. data/CHANGELOG.md +448 -0
  14. data/CONTRIBUTING.md +138 -0
  15. data/Dockerfile +16 -0
  16. data/Gemfile +7 -0
  17. data/Jenkinsfile +136 -0
  18. data/LICENSE +202 -0
  19. data/README.md +162 -0
  20. data/Rakefile +47 -0
  21. data/SECURITY.md +42 -0
  22. data/VERSION +1 -1
  23. data/bin/parse-changelog.sh +12 -0
  24. data/ci/configure_v4.sh +12 -0
  25. data/ci/configure_v5.sh +19 -0
  26. data/ci/oauth/keycloak/create_client +18 -0
  27. data/ci/oauth/keycloak/create_user +21 -0
  28. data/ci/oauth/keycloak/fetch_certificate +18 -0
  29. data/ci/oauth/keycloak/keycloak_functions.sh +71 -0
  30. data/ci/oauth/keycloak/standalone.xml +578 -0
  31. data/ci/oauth/keycloak/wait_for_server +56 -0
  32. data/ci/submit-coverage +36 -0
  33. data/conjur-api.gemspec +41 -0
  34. data/dev/Dockerfile.dev +12 -0
  35. data/dev/docker-compose.yml +56 -0
  36. data/dev/start +22 -0
  37. data/dev/stop +5 -0
  38. data/docker-compose.yml +98 -0
  39. data/example/demo_v4.rb +49 -0
  40. data/example/demo_v5.rb +57 -0
  41. data/features/authenticators.feature +41 -0
  42. data/features/authn.feature +14 -0
  43. data/features/authn_local.feature +32 -0
  44. data/features/exists.feature +37 -0
  45. data/features/group.feature +11 -0
  46. data/features/host.feature +50 -0
  47. data/features/host_factory_create_host.feature +28 -0
  48. data/features/host_factory_token.feature +63 -0
  49. data/features/load_policy.feature +61 -0
  50. data/features/members.feature +51 -0
  51. data/features/new_api.feature +36 -0
  52. data/features/permitted.feature +70 -0
  53. data/features/permitted_roles.feature +30 -0
  54. data/features/public_keys.feature +11 -0
  55. data/features/resource_fields.feature +53 -0
  56. data/features/role_fields.feature +15 -0
  57. data/features/rotate_api_key.feature +13 -0
  58. data/features/step_definitions/api_steps.rb +52 -0
  59. data/features/step_definitions/policy_steps.rb +134 -0
  60. data/features/step_definitions/result_steps.rb +11 -0
  61. data/features/support/env.rb +19 -0
  62. data/features/support/hooks.rb +3 -0
  63. data/features/support/world.rb +12 -0
  64. data/features/update_password.feature +14 -0
  65. data/features/user.feature +58 -0
  66. data/features/variable_fields.feature +20 -0
  67. data/features/variable_value.feature +60 -0
  68. data/features_v4/authn_local.feature +27 -0
  69. data/features_v4/exists.feature +29 -0
  70. data/features_v4/host.feature +18 -0
  71. data/features_v4/host_factory_token.feature +49 -0
  72. data/features_v4/members.feature +39 -0
  73. data/features_v4/permitted.feature +15 -0
  74. data/features_v4/permitted_roles.feature +8 -0
  75. data/features_v4/resource_fields.feature +47 -0
  76. data/features_v4/rotate_api_key.feature +13 -0
  77. data/features_v4/step_definitions/api_steps.rb +17 -0
  78. data/features_v4/step_definitions/result_steps.rb +3 -0
  79. data/features_v4/support/env.rb +23 -0
  80. data/features_v4/support/policy.yml +34 -0
  81. data/features_v4/support/world.rb +12 -0
  82. data/features_v4/variable_fields.feature +11 -0
  83. data/features_v4/variable_value.feature +54 -0
  84. data/lib/conjur/acts_as_resource.rb +123 -0
  85. data/lib/conjur/acts_as_role.rb +142 -0
  86. data/lib/conjur/acts_as_rolsource.rb +32 -0
  87. data/lib/conjur/acts_as_user.rb +68 -0
  88. data/lib/conjur/api/authenticators.rb +43 -0
  89. data/lib/conjur/api/authn.rb +144 -0
  90. data/lib/conjur/api/host_factories.rb +71 -0
  91. data/lib/conjur/api/ldap_sync.rb +38 -0
  92. data/lib/conjur/api/policies.rb +56 -0
  93. data/lib/conjur/api/pubkeys.rb +53 -0
  94. data/lib/conjur/api/resources.rb +109 -0
  95. data/lib/conjur/api/roles.rb +98 -0
  96. data/lib/conjur/api/router/v4.rb +206 -0
  97. data/lib/conjur/api/router/v5.rb +269 -0
  98. data/lib/conjur/api/variables.rb +59 -0
  99. data/lib/conjur/api.rb +105 -0
  100. data/lib/conjur/base.rb +355 -0
  101. data/lib/conjur/base_object.rb +57 -0
  102. data/lib/conjur/build_object.rb +47 -0
  103. data/lib/conjur/cache.rb +26 -0
  104. data/lib/conjur/cert_utils.rb +63 -0
  105. data/lib/conjur/cidr.rb +71 -0
  106. data/lib/conjur/configuration.rb +460 -0
  107. data/lib/conjur/escape.rb +129 -0
  108. data/lib/conjur/exceptions.rb +4 -0
  109. data/lib/conjur/group.rb +41 -0
  110. data/lib/conjur/has_attributes.rb +98 -0
  111. data/lib/conjur/host.rb +27 -0
  112. data/lib/conjur/host_factory.rb +75 -0
  113. data/lib/conjur/host_factory_token.rb +78 -0
  114. data/lib/conjur/id.rb +71 -0
  115. data/lib/conjur/layer.rb +9 -0
  116. data/lib/conjur/log.rb +72 -0
  117. data/lib/conjur/log_source.rb +60 -0
  118. data/lib/conjur/policy.rb +34 -0
  119. data/lib/conjur/policy_load_result.rb +61 -0
  120. data/lib/conjur/query_string.rb +12 -0
  121. data/lib/conjur/resource.rb +29 -0
  122. data/lib/conjur/role.rb +29 -0
  123. data/lib/conjur/role_grant.rb +85 -0
  124. data/lib/conjur/routing.rb +29 -0
  125. data/lib/conjur/user.rb +40 -0
  126. data/lib/conjur/variable.rb +208 -0
  127. data/lib/conjur/webservice.rb +30 -0
  128. data/lib/conjur-api/version.rb +24 -0
  129. data/lib/conjur-api.rb +2 -0
  130. data/publish.sh +5 -0
  131. data/spec/api/host_factories_spec.rb +34 -0
  132. data/spec/api_spec.rb +254 -0
  133. data/spec/base_object_spec.rb +13 -0
  134. data/spec/cert_utils_spec.rb +173 -0
  135. data/spec/cidr_spec.rb +34 -0
  136. data/spec/configuration_spec.rb +330 -0
  137. data/spec/has_attributes_spec.rb +63 -0
  138. data/spec/helpers/errors_matcher.rb +34 -0
  139. data/spec/helpers/request_helpers.rb +10 -0
  140. data/spec/id_spec.rb +29 -0
  141. data/spec/ldap_sync_spec.rb +21 -0
  142. data/spec/log_source_spec.rb +13 -0
  143. data/spec/log_spec.rb +42 -0
  144. data/spec/roles_spec.rb +24 -0
  145. data/spec/spec_helper.rb +113 -0
  146. data/spec/ssl_spec.rb +109 -0
  147. data/spec/uri_escape_spec.rb +21 -0
  148. data/test.sh +76 -0
  149. data/tmp/.keep +0 -0
  150. metadata +194 -3
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2013-2018 CyberArk Ltd.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'conjur/resource'
18
+
19
+ module Conjur
20
+ class API
21
+ include QueryString
22
+ include BuildObject
23
+
24
+ #@!group Resources
25
+
26
+ # Find a resource by its id.
27
+ # @note The id given to this method must be fully qualified.
28
+ #
29
+ # ### Permissions
30
+ #
31
+ # The resource **must** be visible to the current role. This is the case if the current role is the owner of
32
+ # the resource, or has any privilege on it.
33
+ #
34
+ # @param id [String] a fully qualified resource identifier
35
+ # @return [Conjur::Resource] the resource, which may or may not exist
36
+ def resource id
37
+ build_object id
38
+ end
39
+
40
+ # Find all resources visible to the current role that match the given search criteria.
41
+ #
42
+ # ## Full Text Search
43
+ # Conjur supports full text search over the identifiers and annotation *values*
44
+ # of resources. For example, if `opts[:search]` is `"pubkeys"`, any resource with
45
+ # an id containing `"pubkeys"` or an annotation whose value contains `"pubkeys"` will match.
46
+ #
47
+ # **Notes**
48
+ # * Annotation *keys* are *not* indexed for full text search.
49
+ # * Conjur indexes the content of ids and annotation values by word.
50
+ # * Only resources visible to the current role (either owned by that role or
51
+ # having a privilege on it) are returned.
52
+ # * If you do not provide `:offset` or `:limit`, all records will be returned. For systems
53
+ # with a huge number of resources, you may want to paginate as shown in the example below.
54
+ # * If `:offset` is provided and `:limit` is not, 10 records starting at `:offset` will be
55
+ # returned. You may choose an arbitrarily large number for `:limit`, but the same performance
56
+ # considerations apply as when omitting `:offset` and `:limit`.
57
+ #
58
+ # @example Search for resources annotated with the text "WebService Route"
59
+ # webservice_routes = api.resources search: "WebService Route"
60
+ #
61
+ # @example Restrict the search to 'group' resources
62
+ # groups = api.resources kind: 'group'
63
+ #
64
+ # # Correct behavior:
65
+ # expect(groups.all?{|g| g.kind == 'group'}).to be_true
66
+ #
67
+ # @example Get every single resource in a performant way
68
+ # resources = []
69
+ # limit = 25
70
+ # offset = 0
71
+ # until (batch = api.resources limit: limit, offset: offset).empty?
72
+ # offset += batch.length
73
+ # resources.concat results
74
+ # end
75
+ # # do something with your resources
76
+ #
77
+ # @param options [Hash] search criteria
78
+ # @option options [String] :search find resources whose ids or annotations contain this string
79
+ # @option options [String] :kind find resources whose `kind` matches this string
80
+ # @option options [Integer] :limit the maximum number of records to return (Conjur may return fewer)
81
+ # @option options [Integer] :offset offset of the first record to return
82
+ # @option options [Boolean] :count return a count of records instead of the records themselves when set to true
83
+ # @return [Array<Conjur::Resource>] the resources matching the criteria given
84
+ def resources options = {}
85
+ options = { host: Conjur.configuration.core_url, credentials: credentials }.merge options
86
+ options[:account] ||= Conjur.configuration.account
87
+
88
+ host, credentials, account, kind = options.values_at(*[:host, :credentials, :account, :kind])
89
+ fail ArgumentError, "host and account are required" unless [host, account].all?
90
+ %w(host credentials account kind).each do |name|
91
+ options.delete(name.to_sym)
92
+ end
93
+
94
+ result = JSON.parse(url_for(:resources, credentials, account, kind, options).get)
95
+
96
+ result = result['count'] if result.is_a?(Hash)
97
+
98
+ if result.is_a?(Numeric)
99
+ result
100
+ else
101
+ result.map do |result|
102
+ resource(result['id']).tap do |r|
103
+ r.attributes = result
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,98 @@
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/role'
22
+
23
+ module Conjur
24
+ class API
25
+ include BuildObject
26
+
27
+ #@!group Roles
28
+
29
+ # Return a {Conjur::Role} representing a role with the given id. Note that the {Conjur::Role} may or
30
+ # may not exist (see {Conjur::Exists#exists?}).
31
+ #
32
+ # ### Permissions
33
+ #
34
+ # Because this method returns roles that may or may not exist, it doesn't require any permissions to call it:
35
+ # in fact, it does not perform an HTTP request (except for authentication if necessary).
36
+ #
37
+ # @example Create and show a role
38
+ # iggy = api.role 'cat:iggy'
39
+ # iggy.exists? # true
40
+ # iggy.members.map(&:member).map(&:id) # => ['conjur:user:admin']
41
+ # api.current_role.id # => 'conjur:user:admin' # creator role is a member of created role.
42
+ #
43
+ # @example No permissions are required to call this method
44
+ # api.current_role # => "user:no-access"
45
+ #
46
+ # # current role is only a member of itself, so it can't see other roles.
47
+ # api.current_role.memberships.count # => 1
48
+ # admin = api.role 'user:admin' # OK
49
+ # admin.exists? # => true
50
+ # admin.members # => RestClient::Forbidden: 403 Forbidden
51
+ #
52
+ # @param id [String] a fully qualified role identifier
53
+ # @return [Conjur::Role] an object representing the role
54
+ def role id
55
+ build_object id, default_class: Role
56
+ end
57
+
58
+ # Return a {Conjur::Role} object representing the role (typically a user or host) that this API instance is authenticated
59
+ # as. This is derived either from the `login` argument to {Conjur::API.new_from_key} or from the contents of the
60
+ # `token` given to {Conjur::API.new_from_token} or {Conjur::API.new_from_token_file}.
61
+ #
62
+ # @example Current role for a user
63
+ # api = Conjur::API.new_from_key 'jon', 'somepassword'
64
+ # api.current_role.id # => 'conjur:user:jon'
65
+ #
66
+ # @example Current role for a host
67
+ # host = api.create_host id: 'exapmle-host'
68
+ #
69
+ # # Host and User have an `api` method that returns an api with their credentials. Note
70
+ # # that this only works with a newly created host or user, which has an `api_key` attribute.
71
+ # host.api.current_role.id # => 'conjur:host:example-host'
72
+ #
73
+ # @param [String] account the organization account
74
+ # @return [Conjur::Role] the authenticated role for this API instance
75
+ def current_role account
76
+ self.class.role_from_username self, username, account
77
+ end
78
+
79
+ #@!endgroup
80
+
81
+ class << self
82
+ # @api private
83
+ def role_from_username api, username, account
84
+ api.role role_name_from_username(username, account)
85
+ end
86
+
87
+ # @api private
88
+ def role_name_from_username username, account
89
+ tokens = username.split('/')
90
+ if tokens.size == 1
91
+ [ account, 'user', username ].join(':')
92
+ else
93
+ [ account, tokens[0], tokens[1..-1].join('/') ].join(':')
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,206 @@
1
+ module Conjur
2
+ class API
3
+ module Router
4
+ module V4
5
+ extend Conjur::Escape::ClassMethods
6
+ extend Conjur::QueryString
7
+ extend self
8
+
9
+ def authn_login account, username, password
10
+ verify_account(account)
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']
18
+ end
19
+
20
+ def authn_authenticate account, username
21
+ verify_account(account)
22
+ RestClient::Resource.new(
23
+ Conjur.configuration.authn_url,
24
+ Conjur.configuration.rest_client_options
25
+ )['users'][fully_escape username]['authenticate']
26
+ end
27
+
28
+ # For v4, the authn-local message is the username.
29
+ def authn_authenticate_local username, account, expiration, cidr, &block
30
+ verify_account(account)
31
+
32
+ raise "'expiration' is not supported for authn-local v4" if expiration
33
+ raise "'cidr' is not supported for authn-local v4" if cidr
34
+
35
+ username
36
+ end
37
+
38
+ def authn_rotate_api_key credentials, account, id
39
+ verify_account(account)
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}"]
45
+ end
46
+
47
+ def authn_rotate_own_api_key account, username, password
48
+ verify_account(account)
49
+ RestClient::Resource.new(
50
+ Conjur.configuration.authn_url,
51
+ Conjur.configuration.create_rest_client_options(user: username, password: password)
52
+ )['users']["api_key"]
53
+ end
54
+
55
+ def host_factory_create_host token
56
+ http_options = {
57
+ headers: { authorization: %Q(Token token="#{token}") }
58
+ }
59
+ RestClient::Resource.new(
60
+ Conjur.configuration.core_url,
61
+ Conjur.configuration.create_rest_client_options(http_options)
62
+ )['host_factories']['hosts']
63
+ end
64
+
65
+ def host_factory_create_tokens credentials, id
66
+ RestClient::Resource.new(
67
+ Conjur.configuration.core_url,
68
+ Conjur.configuration.create_rest_client_options(credentials)
69
+ )['host_factories'][id.identifier]['tokens']
70
+ end
71
+
72
+ def host_factory_revoke_token credentials, token
73
+ RestClient::Resource.new(
74
+ Conjur.configuration.core_url,
75
+ Conjur.configuration.create_rest_client_options(credentials)
76
+ )['host_factories']['tokens'][token]
77
+ end
78
+
79
+ def resources_resource credentials, id
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]
85
+ end
86
+
87
+ def resources_check credentials, id, privilege, role
88
+ options = {}
89
+ options[:check] = true
90
+ options[:privilege] = privilege
91
+ if role
92
+ options[:resource_id] = id
93
+ roles_role(credentials, Id.new(role))[options_querystring options].get
94
+ else
95
+ resources_resource(credentials, id)[options_querystring options].get
96
+ end
97
+ end
98
+
99
+ def resources_permitted_roles credentials, id, privilege
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]
104
+ end
105
+
106
+ def roles_role credentials, id
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]
111
+ end
112
+
113
+ def secrets_add credentials, id
114
+ verify_account(id.account)
115
+ RestClient::Resource.new(
116
+ Conjur.configuration.core_url,
117
+ Conjur.configuration.create_rest_client_options(credentials)
118
+ )['variables'][fully_escape id.identifier]['values']
119
+ end
120
+
121
+ def variable credentials, id
122
+ verify_account(id.account)
123
+ RestClient::Resource.new(
124
+ Conjur.configuration.core_url,
125
+ Conjur.configuration.create_rest_client_options(credentials)
126
+ )['variables'][fully_escape id.identifier]
127
+ end
128
+
129
+ def secrets_value credentials, id, options
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]
134
+ end
135
+
136
+ def secrets_values credentials, variable_ids
137
+ options = {
138
+ vars: Array(variable_ids).map { |v| fully_escape(v.identifier) }.join(',')
139
+ }
140
+ RestClient::Resource.new(
141
+ Conjur.configuration.core_url,
142
+ Conjur.configuration.create_rest_client_options(credentials)
143
+ )['variables']['values'][options_querystring options]
144
+ end
145
+
146
+ def group_attributes credentials, resource, id
147
+ verify_account(id.account)
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
+ )
154
+ end
155
+
156
+ def variable_attributes credentials, resource, id
157
+ verify_account(id.account)
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
+ )
164
+ end
165
+
166
+ def user_attributes credentials, resource, id
167
+ verify_account(id.account)
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
+ )
174
+ end
175
+
176
+ def parse_group_gidnumber attributes
177
+ attributes['gidnumber']
178
+ end
179
+
180
+ def parse_user_uidnumber attributes
181
+ attributes['uidnumber']
182
+ end
183
+
184
+ def parse_variable_kind attributes
185
+ attributes['kind']
186
+ end
187
+
188
+ def parse_variable_mime_type attributes
189
+ attributes['mime_type']
190
+ end
191
+
192
+ def parse_members credentials, result
193
+ result.collect do |json|
194
+ RoleGrant.parse_from_json(json, credentials)
195
+ end
196
+ end
197
+
198
+ protected
199
+
200
+ def verify_account account
201
+ raise "Expecting account to be #{Conjur.configuration.account.inspect}, got #{account.inspect}" unless Conjur.configuration.account == account
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,269 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2017-2018 CyberArk Ltd.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ # rubocop:disable Metrics/ModuleLength
18
+ module Conjur
19
+ class API
20
+ module Router
21
+ # V5 translates method arguments to rest-ful API request parameters.
22
+ # because of this, most of the methods suffer from :reek:LongParameterList:
23
+ # and :reek:UtilityFunction:
24
+ module V5
25
+ extend Conjur::Escape::ClassMethods
26
+ extend Conjur::QueryString
27
+ extend self
28
+
29
+ def authn_login account, username, password
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']
37
+ end
38
+
39
+ def authn_authenticate account, username
40
+ RestClient::Resource.new(
41
+ Conjur.configuration.authn_url,
42
+ Conjur.configuration.rest_client_options
43
+ )[fully_escape account][fully_escape username]['authenticate']
44
+ end
45
+
46
+ def authenticator_authenticate(account, service_id, authenticator, options)
47
+ RestClient::Resource.new(
48
+ Conjur.configuration.core_url,
49
+ Conjur.configuration.rest_client_options
50
+ )[fully_escape authenticator][fully_escape service_id][fully_escape account]['authenticate'][options_querystring options]
51
+ end
52
+
53
+ def authenticator account, authenticator, service_id, credentials
54
+ RestClient::Resource.new(
55
+ Conjur.configuration.core_url,
56
+ Conjur.configuration.create_rest_client_options(credentials)
57
+ )[fully_escape authenticator][fully_escape service_id][fully_escape account]
58
+ end
59
+
60
+ def authenticators
61
+ RestClient::Resource.new(
62
+ Conjur.configuration.core_url,
63
+ Conjur.configuration.rest_client_options
64
+ )['authenticators']
65
+ end
66
+
67
+ def authentication_providers(account, authenticator, credentials)
68
+ RestClient::Resource.new(
69
+ Conjur.configuration.core_url,
70
+ Conjur.configuration.create_rest_client_options(credentials)
71
+ )[fully_escape authenticator][fully_escape account]['providers']
72
+ end
73
+
74
+ # For v5, the authn-local message is a JSON string with account, sub, and optional fields.
75
+ def authn_authenticate_local username, account, expiration, cidr, &block
76
+ { account: account, sub: username }.tap do |params|
77
+ params[:exp] = expiration if expiration
78
+ params[:cidr] = cidr if cidr
79
+ end.to_json
80
+ end
81
+
82
+ def authn_update_password account, username, password
83
+ RestClient::Resource.new(
84
+ Conjur.configuration.authn_url,
85
+ Conjur.configuration.create_rest_client_options(
86
+ user: username,
87
+ password: password
88
+ )
89
+ )[fully_escape account]['password']
90
+ end
91
+
92
+ def authn_rotate_api_key credentials, account, id
93
+ RestClient::Resource.new(
94
+ Conjur.configuration.core_url,
95
+ Conjur.configuration.create_rest_client_options(credentials)
96
+ )['authn'][fully_escape account]["api_key?role=#{id}"]
97
+ end
98
+
99
+ def authn_rotate_own_api_key account, username, password
100
+ RestClient::Resource.new(
101
+ Conjur.configuration.authn_url,
102
+ Conjur.configuration.create_rest_client_options(
103
+ user: username,
104
+ password: password
105
+ )
106
+ )[fully_escape account]['api_key']
107
+ end
108
+
109
+ def host_factory_create_host token
110
+ http_options = {
111
+ headers: { authorization: %Q(Token token="#{token}") }
112
+ }
113
+ RestClient::Resource.new(
114
+ Conjur.configuration.core_url,
115
+ Conjur.configuration.create_rest_client_options(http_options)
116
+ )["host_factories"]["hosts"]
117
+ end
118
+
119
+ def host_factory_create_tokens credentials, id
120
+ RestClient::Resource.new(
121
+ Conjur.configuration.core_url,
122
+ Conjur.configuration.create_rest_client_options(credentials)
123
+ )['host_factory_tokens']
124
+ end
125
+
126
+ def host_factory_revoke_token credentials, token
127
+ RestClient::Resource.new(
128
+ Conjur.configuration.core_url,
129
+ Conjur.configuration.create_rest_client_options(credentials)
130
+ )['host_factory_tokens'][token]
131
+ end
132
+
133
+ def policies_load_policy credentials, account, id
134
+ RestClient::Resource.new(
135
+ Conjur.configuration.core_url,
136
+ Conjur.configuration.create_rest_client_options(credentials)
137
+ )['policies'][fully_escape account]['policy'][fully_escape id]
138
+ end
139
+
140
+ def public_keys_for_user account, username
141
+ RestClient::Resource.new(
142
+ Conjur.configuration.core_url,
143
+ Conjur.configuration.rest_client_options
144
+ )['public_keys'][fully_escape account]['user'][fully_escape username]
145
+ end
146
+
147
+ def resources credentials, account, kind, options
148
+ credentials ||= {}
149
+
150
+ path = "/resources/#{fully_escape account}"
151
+ path += "/#{fully_escape kind}" if kind
152
+
153
+ RestClient::Resource.new(
154
+ Conjur.configuration.core_url,
155
+ Conjur.configuration.create_rest_client_options(credentials)
156
+ )[path][options_querystring options]
157
+ end
158
+
159
+ def resources_resource credentials, id
160
+ RestClient::Resource.new(
161
+ Conjur.configuration.core_url,
162
+ Conjur.configuration.create_rest_client_options(credentials)
163
+ )['resources'][id.to_url_path]
164
+ end
165
+
166
+ def resources_permitted_roles credentials, id, privilege
167
+ options = {}
168
+ options[:permitted_roles] = true
169
+ options[:privilege] = privilege
170
+ resources_resource(credentials, id)[options_querystring options]
171
+ end
172
+
173
+ def resources_check credentials, id, privilege, role
174
+ options = {}
175
+ options[:check] = true
176
+ options[:privilege] = privilege
177
+ options[:role] = query_escape(Id.new(role)) if role
178
+ resources_resource(credentials, id)[options_querystring options].get
179
+ end
180
+
181
+ def roles_role credentials, id
182
+ RestClient::Resource.new(
183
+ Conjur.configuration.core_url,
184
+ Conjur.configuration.create_rest_client_options(credentials)
185
+ )['roles'][id.to_url_path]
186
+ end
187
+
188
+ def secrets_add credentials, id
189
+ RestClient::Resource.new(
190
+ Conjur.configuration.core_url,
191
+ Conjur.configuration.create_rest_client_options(credentials)
192
+ )['secrets'][id.to_url_path]
193
+ end
194
+
195
+ def secrets_value credentials, id, options
196
+ RestClient::Resource.new(
197
+ Conjur.configuration.core_url,
198
+ Conjur.configuration.create_rest_client_options(credentials)
199
+ )['secrets'][id.to_url_path][options_querystring options]
200
+ end
201
+
202
+ def secrets_values credentials, variable_ids
203
+ options = {
204
+ variable_ids: Array(variable_ids).join(',')
205
+ }
206
+ RestClient::Resource.new(
207
+ Conjur.configuration.core_url,
208
+ Conjur.configuration.create_rest_client_options(credentials)
209
+ )['secrets'][options_querystring(options).gsub("%2C", ',')]
210
+ end
211
+
212
+ def group_attributes credentials, resource, id
213
+ resource_annotations resource
214
+ end
215
+
216
+ def variable_attributes credentials, resource, id
217
+ resource_annotations resource
218
+ end
219
+
220
+ def user_attributes credentials, resource, id
221
+ resource_annotations resource
222
+ end
223
+
224
+ def parse_group_gidnumber attributes
225
+ HasAttributes.annotation_value attributes, 'conjur/gidnumber'
226
+ end
227
+
228
+ def parse_user_uidnumber attributes
229
+ HasAttributes.annotation_value attributes, 'conjur/uidnumber'
230
+ end
231
+
232
+ def parse_variable_kind attributes
233
+ HasAttributes.annotation_value attributes, 'conjur/kind'
234
+ end
235
+
236
+ def parse_variable_mime_type attributes
237
+ HasAttributes.annotation_value attributes, 'conjur/mime_type'
238
+ end
239
+
240
+ def parse_members credentials, result
241
+ result.map do |json|
242
+ RoleGrant.parse_from_json(json, credentials)
243
+ end
244
+ end
245
+
246
+ def ldap_sync_policy(credentials, config_name)
247
+ RestClient::Resource.new(
248
+ Conjur.configuration.core_url,
249
+ Conjur.configuration.create_rest_client_options(credentials)
250
+ )['ldap-sync']["policy?config_name=#{fully_escape(config_name)}"]
251
+ end
252
+
253
+ def whoami(credentials)
254
+ RestClient::Resource.new(
255
+ Conjur.configuration.core_url,
256
+ Conjur.configuration.create_rest_client_options(credentials)
257
+ )['whoami']
258
+ end
259
+
260
+ private
261
+
262
+ def resource_annotations resource
263
+ resource.attributes['annotations']
264
+ end
265
+ end
266
+ end
267
+ end
268
+ end
269
+ # rubocop:enable Metrics/ModuleLength