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.
Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +1 -0
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +22 -3
  5. data/Dockerfile +12 -3
  6. data/Gemfile +3 -3
  7. data/Jenkinsfile +69 -0
  8. data/LICENSE.md +195 -0
  9. data/README.md +16 -0
  10. data/Rakefile +34 -18
  11. data/ci/wait_for_server.sh +10 -0
  12. data/conjur-api.gemspec +6 -14
  13. data/dev/docker-compose.yml +23 -0
  14. data/dev/empty.yml +2 -0
  15. data/dev/start.sh +15 -0
  16. data/dev/stop.sh +6 -0
  17. data/docker-compose.yml +27 -0
  18. data/features/exists.feature +37 -0
  19. data/features/group.feature +11 -0
  20. data/features/host.feature +20 -0
  21. data/features/host_factory_create_host.feature +28 -0
  22. data/features/host_factory_token.feature +63 -0
  23. data/features/load_policy.feature +61 -0
  24. data/features/members.feature +51 -0
  25. data/features/new_api.feature +36 -0
  26. data/features/permitted.feature +43 -0
  27. data/features/permitted_roles.feature +30 -0
  28. data/features/public_keys.feature +11 -0
  29. data/features/resource_fields.feature +53 -0
  30. data/features/role_fields.feature +15 -0
  31. data/features/rotate_api_key.feature +13 -0
  32. data/features/step_definitions/api_steps.rb +4 -54
  33. data/features/step_definitions/policy_steps.rb +35 -0
  34. data/features/step_definitions/result_steps.rb +7 -0
  35. data/features/support/env.rb +14 -5
  36. data/features/support/hooks.rb +3 -0
  37. data/features/support/world.rb +5 -6
  38. data/features/update_password.feature +14 -0
  39. data/features/user.feature +17 -0
  40. data/features/variable_fields.feature +20 -0
  41. data/features/variable_value.feature +67 -0
  42. data/lib/conjur/acts_as_resource.rb +95 -65
  43. data/lib/conjur/acts_as_role.rb +102 -51
  44. data/lib/conjur/{audit-api.rb → acts_as_rolsource.rb} +10 -14
  45. data/lib/conjur/acts_as_user.rb +13 -22
  46. data/lib/conjur/api/authn.rb +37 -72
  47. data/lib/conjur/api/host_factories.rb +35 -55
  48. data/lib/conjur/api/policies.rb +56 -0
  49. data/lib/conjur/api/pubkeys.rb +36 -160
  50. data/lib/conjur/api/resources.rb +32 -116
  51. data/lib/conjur/api/roles.rb +28 -105
  52. data/lib/conjur/api/variables.rb +22 -91
  53. data/lib/conjur/api.rb +19 -46
  54. data/lib/conjur/base.rb +21 -132
  55. data/lib/conjur/base_object.rb +57 -0
  56. data/lib/conjur/{authn-api.rb → build_object.rb} +23 -11
  57. data/lib/conjur/cast.rb +12 -17
  58. data/lib/conjur/cert_utils.rb +1 -1
  59. data/lib/conjur/cidr.rb +1 -1
  60. data/lib/conjur/configuration.rb +13 -91
  61. data/lib/conjur/escape.rb +1 -2
  62. data/lib/conjur/group.rb +9 -65
  63. data/lib/conjur/has_attributes.rb +22 -59
  64. data/lib/conjur/host.rb +5 -35
  65. data/lib/conjur/host_factory.rb +40 -40
  66. data/lib/conjur/host_factory_token.rb +38 -23
  67. data/lib/conjur/id.rb +63 -0
  68. data/lib/conjur/layer.rb +5 -80
  69. data/lib/conjur/log.rb +1 -1
  70. data/lib/conjur/log_source.rb +1 -1
  71. data/lib/conjur/{secret.rb → policy.rb} +11 -14
  72. data/lib/conjur/{api/secrets.rb → policy_load_result.rb} +35 -22
  73. data/lib/conjur/query_string.rb +2 -1
  74. data/lib/conjur/resource.rb +5 -299
  75. data/lib/conjur/role.rb +5 -317
  76. data/lib/conjur/role_grant.rb +20 -28
  77. data/lib/conjur/user.rb +5 -63
  78. data/lib/conjur/variable.rb +31 -76
  79. data/lib/conjur/{authz-api.rb → webservice.rb} +8 -16
  80. data/lib/conjur-api/version.rb +2 -2
  81. data/publish.sh +7 -0
  82. data/spec/api_spec.rb +208 -0
  83. data/spec/cast_spec.rb +21 -0
  84. data/spec/{lib/cert_utils_spec.rb → cert_utils_spec.rb} +0 -0
  85. data/spec/{lib/cidr_spec.rb → cidr_spec.rb} +0 -0
  86. data/spec/{lib/configuration_spec.rb → configuration_spec.rb} +40 -140
  87. data/spec/{lib/has_attributes_spec.rb → has_attributes_spec.rb} +6 -2
  88. data/spec/{lib/log_source_spec.rb → log_source_spec.rb} +0 -0
  89. data/spec/{lib/log_spec.rb → log_spec.rb} +0 -0
  90. data/spec/roles_spec.rb +24 -0
  91. data/spec/spec_helper.rb +63 -78
  92. data/spec/ssl_spec.rb +3 -5
  93. data/spec/vendor/rest_client_spec.rb +0 -54
  94. data/test.sh +40 -0
  95. metadata +122 -281
  96. data/.kateproject +0 -5
  97. data/LICENSE +0 -22
  98. data/ci/test.sh +0 -9
  99. data/features/audit_resources.feature +0 -15
  100. data/features/audit_roles.feature +0 -15
  101. data/features/bootstrap.feature +0 -31
  102. data/features/step_definitions/cli_steps.rb +0 -5
  103. data/jenkins.sh +0 -27
  104. data/lib/conjur/acts_as_asset.rb +0 -88
  105. data/lib/conjur/annotations.rb +0 -186
  106. data/lib/conjur/api/audit.rb +0 -138
  107. data/lib/conjur/api/deputies.rb +0 -57
  108. data/lib/conjur/api/groups.rb +0 -111
  109. data/lib/conjur/api/hosts.rb +0 -109
  110. data/lib/conjur/api/info.rb +0 -126
  111. data/lib/conjur/api/layers.rb +0 -62
  112. data/lib/conjur/api/ldapsync.rb +0 -115
  113. data/lib/conjur/api/users.rb +0 -106
  114. data/lib/conjur/bootstrap.rb +0 -161
  115. data/lib/conjur/build_from_response.rb +0 -49
  116. data/lib/conjur/core-api.rb +0 -74
  117. data/lib/conjur/deputy.rb +0 -55
  118. data/lib/conjur/env.rb +0 -54
  119. data/lib/conjur/event_source.rb +0 -101
  120. data/lib/conjur/exists.rb +0 -60
  121. data/lib/conjur/graph.rb +0 -295
  122. data/lib/conjur/has_id.rb +0 -43
  123. data/lib/conjur/has_identifier.rb +0 -36
  124. data/lib/conjur/has_owner.rb +0 -51
  125. data/lib/conjur/host-factory-api.rb +0 -38
  126. data/lib/conjur/layer-api.rb +0 -13
  127. data/lib/conjur/ldap_sync_job.rb +0 -89
  128. data/lib/conjur/path_based.rb +0 -86
  129. data/lib/conjur/pubkeys-api.rb +0 -50
  130. data/lib/conjur/standard_methods.rb +0 -91
  131. data/reqspeed.rb +0 -20
  132. data/spec/api/authn_spec.rb +0 -81
  133. data/spec/api/graph_spec.rb +0 -117
  134. data/spec/api/groups_spec.rb +0 -40
  135. data/spec/api/hosts_spec.rb +0 -36
  136. data/spec/api/info_spec.rb +0 -89
  137. data/spec/api/layer_spec.rb +0 -18
  138. data/spec/api/ldapsync_spec.rb +0 -44
  139. data/spec/api/pubkeys_spec.rb +0 -66
  140. data/spec/api/resources_spec.rb +0 -92
  141. data/spec/api/roles_spec.rb +0 -100
  142. data/spec/api/secrets_spec.rb +0 -16
  143. data/spec/api/users_spec.rb +0 -71
  144. data/spec/api/variables_spec.rb +0 -112
  145. data/spec/cas_rest_client.rb +0 -17
  146. data/spec/cidr_helper.rb +0 -24
  147. data/spec/lib/acts_as_user_spec.rb +0 -27
  148. data/spec/lib/annotations_spec.rb +0 -109
  149. data/spec/lib/api_spec.rb +0 -480
  150. data/spec/lib/asset_spec.rb +0 -80
  151. data/spec/lib/audit_spec.rb +0 -155
  152. data/spec/lib/build_from_response_spec.rb +0 -49
  153. data/spec/lib/deputy_spec.rb +0 -25
  154. data/spec/lib/exists_spec.rb +0 -24
  155. data/spec/lib/group_spec.rb +0 -18
  156. data/spec/lib/host_spec.rb +0 -31
  157. data/spec/lib/resource_spec.rb +0 -240
  158. data/spec/lib/role_grant_spec.rb +0 -13
  159. data/spec/lib/role_spec.rb +0 -231
  160. data/spec/lib/standard_methods_spec.rb +0 -66
  161. data/spec/lib/user_spec.rb +0 -77
  162. data/spec/standard_methods_helper.rb +0 -41
  163. data/spec/variable_spec.rb +0 -101
  164. data/spec/vcr_cassettes/Conjur_Resource/_create/with_path-like_identifier.yml +0 -87
  165. data/spec/vcr_cassettes/Conjur_Resource/_create/with_un-encoded_path-like_identifier.yml +0 -87
  166. data/spec/vcr_cassettes/Conjur_Resource/_create/with_uuid_identifier.yml +0 -87
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013 Conjur Inc
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,44 +22,11 @@ require 'conjur/resource'
22
22
 
23
23
  module Conjur
24
24
  class API
25
- #@!group Authorization: Resources
26
-
27
- # Create a {http://developer.conjur.net/reference/services/authorization/resource Conjur Resource}.
28
- # Resources are entities on which roles have permissions. A resource might represent a secret, a
29
- # web service route, or be part of a higher level construct such as a user or group.
30
- #
31
- # If `:acting_as` is not present in `options`, you will be the owner of the new role. If it is present,
32
- # your role must be a member of the given role (see {Conjur::Role#member_of?}).
33
- #
34
- # @example Create an abstract resource to represent a web service route
35
- # # Notice that we can omit the account in the identifier
36
- # service_resource = api.create_resource 'web-service:list-gadgets'
37
- # service_resource.resource_id # => 'conjur:web-service:list-gadgets'
38
- #
39
- # # In a gatekeeper for the web service, we can use the resource to control access
40
- # get '/gadgets' do
41
- # # We'll assume that we've verified the Conjur authn token in the request, and stored the
42
- # # corresponding identifier in `request_role_id`
43
- # halt(403) unless api.resource('conjur:web-service:list-gadgets').permitted? 'read', request_role_id
44
- # render_json find_gadgets
45
- # end
46
- #
47
- # @example Create a role owned by another role
48
- # alice = api.role('user:alice')
49
- # api.current_role.member_of? alice # true, the operation will fail if this is false
50
- # res = api.create_resource 'example:owned', acting_as: 'user:alice'
51
- # res.owner # "conjur:user:alice"
52
- #
53
- # @param [String] identifier an id of the form `"<account>:<kind>:<id>"` or `"<kind>:<id>"`
54
- # @param options [Hash] options for the request
55
- # @option options [String, #role_id] :acting_as the role-ish thing or role id that will own the new resource
56
- # @return [Conjur::Role] the new role
57
- def create_resource(identifier, options = {})
58
- resource(identifier).tap do |r|
59
- r.create(options)
60
- end
61
- end
25
+ include QueryString
26
+ include BuildObject
62
27
 
28
+ #@!group Resources
29
+
63
30
  # Find a resource by it's id. The id given to this method must be qualified by a kind, but the account is
64
31
  # optional.
65
32
  #
@@ -68,23 +35,10 @@ module Conjur
68
35
  # The resource **must** be visible to the current role. This is the case if the current role is the owner of
69
36
  # the resource, or has any privilege on it.
70
37
  #
71
- # @example Find or create a resource
72
- # def find_or_create_resource resource_id
73
- # resource = api.resource resource_id
74
- # unless resource.exists?
75
- # resource = api.create_resource resource_id
76
- # end
77
- # resource
78
- # end
79
- #
80
- # # ...
81
- # example_resource = find_or_create_resource 'example:find-or-create'
82
- # example_resource.exists? # always true
83
- #
84
- # @param identifier [String] a qualified resource identifier, optionally including an account
38
+ # @param id [String] a fully qualified resource identifier
85
39
  # @return [Conjur::Resource] the resource, which may or may not exist
86
- def resource identifier
87
- Resource.new(Conjur::Authz::API.host, credentials)[self.class.parse_resource_id(identifier).join('/')]
40
+ def resource id
41
+ build_object id
88
42
  end
89
43
 
90
44
  # Find all resources visible to the current role that match the given search criteria.
@@ -108,19 +62,12 @@ module Conjur
108
62
  # @example Search for resources annotated with the text "WebService Route"
109
63
  # webservice_routes = api.resources search: "WebService Route"
110
64
  #
111
- # # Check that it worked:
112
- # webservice_routes.each do |resource|
113
- # searchable = [resource.annotations.to_h.values, resource.resource_id]
114
- # raise "FAILED" unless searchable.flatten.any?{|s| s.include? "WebService Route"}
115
- # end
116
- #
117
65
  # @example Restrict the search to 'group' resources
118
66
  # groups = api.resources kind: 'group'
119
67
  #
120
68
  # # Correct behavior:
121
69
  # expect(groups.all?{|g| g.kind == 'group'}).to be_true
122
70
  #
123
- #
124
71
  # @example Get every single resource in a performant way
125
72
  # resources = []
126
73
  # limit = 25
@@ -131,17 +78,32 @@ module Conjur
131
78
  # end
132
79
  # # do something with your resources
133
80
  #
134
- # @param opts [Hash] search criteria
135
- # @option opts [String] :search find resources whose ids or annotations contain this string
136
- # @option opts [String] :kind find resources whose `kind` matches this string
137
- # @option opts [Integer] :limit the maximum number of records to return (Conjur may return fewer)
138
- # @option opts [Integer] :offset offset of the first record to return
81
+ # @param options [Hash] search criteria
82
+ # @option options [String] :search find resources whose ids or annotations contain this string
83
+ # @option options [String] :kind find resources whose `kind` matches this string
84
+ # @option options [Integer] :limit the maximum number of records to return (Conjur may return fewer)
85
+ # @option options [Integer] :offset offset of the first record to return
86
+ # @option options [Boolean] :count return a count of records instead of the records themselves when set to true
139
87
  # @return [Array<Conjur::Resource>] the resources matching the criteria given
140
- def resources opts = {}
141
- opts = { host: Conjur::Authz::API.host, credentials: credentials }.merge opts
142
- opts[:account] ||= Conjur.account
88
+ def resources options = {}
89
+ options = { host: Conjur.configuration.core_url, credentials: credentials }.merge options
90
+ options[:account] ||= Conjur.configuration.account
143
91
 
144
- result = Resource.all(opts)
92
+ host, credentials, account, kind = options.values_at(*[:host, :credentials, :account, :kind])
93
+ fail ArgumentError, "host and account are required" unless [host, account].all?
94
+ %w(host credentials account kind).each do |name|
95
+ options.delete(name.to_sym)
96
+ end
97
+
98
+ credentials ||= {}
99
+
100
+ path = "/resources/#{path_escape account}"
101
+ path += "/#{path_escape kind}" if kind
102
+
103
+ result = JSON.parse(RestClient::Resource.new(Conjur.configuration.core_url, credentials)[path][options_querystring options].get)
104
+
105
+ result = result['count'] if result.is_a?(Hash)
106
+
145
107
  if result.is_a?(Numeric)
146
108
  result
147
109
  else
@@ -152,51 +114,5 @@ module Conjur
152
114
  end
153
115
  end
154
116
  end
155
-
156
- # The resource which grants global privileges to Conjur.
157
- # Privileges given on this resource apply to any record in the system.
158
- # There are two defined global privileges:
159
- #
160
- # * **elevate** permission is granted for any action.
161
- # * **reveal** methods which list records will always return every matching
162
- # record, regardless of whether the user has any privileges on these records or not.
163
- # Services can also choose to attach additional semantics to *reveal*, such as allowing
164
- # the user to show non-sensitive attributes of any record.
165
- #
166
- # Global privileges are available in Conjur 4.5 and later.
167
- GLOBAL_PRIVILEGE_RESOURCE = "!:!:conjur"
168
-
169
- # Checks whether the client has a particular global privilege.
170
- # The global privileges are *elevate* and *reveal*.
171
- def global_privilege_permitted? privilege
172
- resource(GLOBAL_PRIVILEGE_RESOURCE).permitted? privilege
173
- end
174
-
175
- # Check to see if the logged-in role has the specified +privilege+
176
- # on the resources specified by +kind+ and +identifiers+.
177
- #
178
- # @example
179
- # secret1 = api.create_variable 'text/plain', 'secret1', id: 'secret1', value: 'my_first_secret'
180
- # secret2 = api.create_variable 'text/plain', 'secret2', id: 'secret2', value: 'another_secret'
181
- # all_permitted, results = api.resources_permitted? 'variable', ['secret1', 'secret2'], 'execute'
182
-
183
- # @param [String] kind the kind of resources to check
184
- # @param [Array<String>] identifiers the (unqualified) identifiers of the resources
185
- # @param [String] privilege the privilege to check for
186
- # @return [Array] first element is a Boolean, true if all checks passed, false otherwise.
187
- # If some checks fail, second element is the check result for each resource.
188
- def resources_permitted? kind, identifiers, privilege
189
- options = {
190
- privilege: privilege,
191
- identifiers: identifiers
192
- }
193
- resp = RestClient::Resource.new(Conjur::Authz::API.host, credentials)["#{Conjur.account}/resources/#{kind}?check=true"].post(options)
194
- if resp.code == 204
195
- [true, []]
196
- else
197
- [false, JSON.parse(resp.body)]
198
- end
199
- end
200
-
201
117
  end
202
118
  end
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013 Conjur Inc
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
@@ -19,82 +19,26 @@
19
19
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  #
21
21
  require 'conjur/role'
22
- require 'conjur/graph'
23
22
 
24
23
  module Conjur
25
24
  class API
26
- #@!group Authorization: Roles
25
+ include BuildObject
27
26
 
28
- # Fetch a {Conjur::Graph} representing the relationships of a given role or roles. Such graphs are transitive,
29
- # and follow the normal permissions for role visibility.
30
- #
31
- # @param [Array<Conjur::Role, String>, String, Conjur::Role] roles role or or array of roles
32
- # roles whose relationships we're interested in
33
- # @param [Hash] options options for the request
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
- # @option options [Conjur::Role, String] :as_role Only roles visible to this role will be included in the graph
37
- # @return [Conjur::Graph] An object representing the role memberships digraph
38
- def role_graph roles, options = {}
39
- roles = [roles] unless roles.kind_of? Array
40
- roles.map!{|r| normalize_roleid(r) }
41
- options[:as_role] = normalize_roleid(options[:as_role]) if options.include?(:as_role)
42
- options.reverse_merge! as_role: normalize_roleid(current_role), descendants: true, ancestors: true
43
-
44
- query = {from_role: options.delete(:as_role)}
45
- .merge(options.slice(:ancestors, :descendants))
46
- .merge(roles: roles).to_query
47
- Conjur::Graph.new RestClient::Resource.new(Conjur::Authz::API.host, credentials)["#{Conjur.account}/roles?#{query}"].get
48
- end
49
-
50
- # Create a {Conjur::Role} with the given id.
51
- #
52
- # ### Permissions
53
- # * All Conjur roles can create new roles.
54
- # * The creator role (either the current role or the role given by the `:acting_as` option)
55
- # is made a member of the new role. The new role is also made a member of itself.
56
- # * If you give an `:acting_as` option, you must be a (transitive) member of the `:acting_as`
57
- # role.
58
- # * The new role is granted to the creator role with *admin option*: that is, the creator role
59
- # is able to grant the created role to other roles.
60
- #
61
- # @example Basic role creation
62
- # # Current role is 'user:jon', assume the organizational account is 'conjur'
63
- # api.current_role # => 'conjur:user:jon'
64
- #
65
- # # Create a Conjur actor to control the permissions of a chron job (rebuild_indices)
66
- # role = api.create_role 'robot:rebuild_indices'
67
- # role.role_id # => "conjur:robot:rebuild_indices"
68
- # role.members.map{ |grant| grant.member.role_id } # => ['conjur:user:jon', 'conjur:robot:rebuild_indices']
69
- # api.role('user:jon').admin_of?(role) # => true
70
- #
71
- #
72
- # @param [String] role a qualified role identifier for the new role
73
- # @param [Hash] options options for the action
74
- # @option options [String] :acting_as the resource will effectively be created by this role
75
- # @return [Conjur::Role] the created role
76
- # @raise [RestClient::MethodNotAllowed] if the role already exists. Note that this differs from
77
- # the `RestClient::Conflict` exception raised when trying to create existing high level (user, group, etc.)
78
- # Conjur assets.
79
- def create_role(role, options = {})
80
- role(role).tap do |r|
81
- r.create(options)
82
- end
83
- end
27
+ #@!group Roles
84
28
 
85
29
  # Return a {Conjur::Role} representing a role with the given id. Note that the {Conjur::Role} may or
86
30
  # may not exist (see {Conjur::Exists#exists?}).
87
31
  #
88
32
  # ### Permissions
33
+ #
89
34
  # Because this method returns roles that may or may not exist, it doesn't require any permissions to call it:
90
35
  # in fact, it does not perform an HTTP request (except for authentication if necessary).
91
36
  #
92
37
  # @example Create and show a role
93
- # api.create_role 'cat:iggy'
94
38
  # iggy = api.role 'cat:iggy'
95
39
  # iggy.exists? # true
96
- # iggy.members.map(&:member).map(&:roleid) # => ['conjur:user:admin']
97
- # api.current_role.roleid # => 'conjur:user:admin' # creator role is a member of created role.
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.
98
42
  #
99
43
  # @example No permissions are required to call this method
100
44
  # api.current_role # => "user:no-access"
@@ -105,70 +49,49 @@ module Conjur
105
49
  # admin.exists? # => true
106
50
  # admin.members # => RestClient::Forbidden: 403 Forbidden
107
51
  #
108
- # @param [String] role the id of the role, which must contain at least kind and id tokens (account is optional).
52
+ # @param id [String] a fully qualified role identifier
109
53
  # @return [Conjur::Role] an object representing the role
110
- def role role
111
- Role.new(Conjur::Authz::API.host, credentials)[self.class.parse_role_id(role).join('/')]
54
+ def role id
55
+ build_object id, default_class: Role
112
56
  end
113
57
 
114
- # Return a {Conjur::Role} object representing the role (typically a user or host) that this api is authenticated
58
+ # Return a {Conjur::Role} object representing the role (typically a user or host) that this API instance is authenticated
115
59
  # as. This is derived either from the `login` argument to {Conjur::API.new_from_key} or from the contents of the
116
- # `token` given to {Conjur::API.new_from_token}.
60
+ # `token` given to {Conjur::API.new_from_token} or {Conjur::API.new_from_token_file}.
117
61
  #
118
62
  # @example Current role for a user
119
63
  # api = Conjur::API.new_from_key 'jon', 'somepassword'
120
- # api.current_role.roleid # => 'conjur:user:jon'
64
+ # api.current_role.id # => 'conjur:user:jon'
121
65
  #
122
66
  # @example Current role for a host
123
67
  # host = api.create_host id: 'exapmle-host'
124
68
  #
125
69
  # # Host and User have an `api` method that returns an api with their credentials. Note
126
70
  # # that this only works with a newly created host or user, which has an `api_key` attribute.
127
- # host.api.current_role.roleid # => 'conjur:host:example-host'
71
+ # host.api.current_role.id # => 'conjur:host:example-host'
128
72
  #
73
+ # @param [String] account the organization account
129
74
  # @return [Conjur::Role] the authenticated role for this API instance
130
- def current_role
131
- role_from_username username
75
+ def current_role account
76
+ self.class.role_from_username self, username, account
132
77
  end
133
78
 
134
79
  #@!endgroup
135
80
 
136
- # @api private
137
- #
138
- # Get a Role instance from a username or host id
139
- # @param [String] username the username or host id
140
- # @return [Conjur::Role]
141
- def role_from_username username
142
- role(role_name_from_username username)
143
- end
144
-
145
- # @api private
146
- #
147
- # Convert a username or host id to a role identifier.
148
- # This handles conversion of logins like 'host/foo' to 'host:foo'
149
- # @param [String] username the user name or host id
150
- # @return [String] A full role id for the user or host
151
- def role_name_from_username username = self.username
152
- tokens = username.split('/')
153
- if tokens.size == 1
154
- [ 'user', username ].join(':')
155
- else
156
- [ tokens[0], tokens[1..-1].join('/') ].join(':')
81
+ class << self
82
+ # @api private
83
+ def role_from_username api, username, account
84
+ api.role role_name_from_username(username, account)
157
85
  end
158
- end
159
-
160
- private
161
86
 
162
- # @api private
163
- # Use of this method is deprecated in favor of Conjur::Cast#cast
164
- # @deprecated
165
- # @param [String, Conjur::Role] role object to extract a role id from
166
- # @return [String] the role id
167
- def normalize_roleid role
168
- case role
169
- when String then role
170
- when Role then role.roleid
171
- else raise "Can't normalize #{role}@#{role.class}"
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
172
95
  end
173
96
  end
174
97
  end
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013 Conjur Inc
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,54 +22,8 @@ require 'conjur/variable'
22
22
 
23
23
  module Conjur
24
24
  class API
25
- #@!group Directory: Variables
26
-
27
- # Create a {http://developer.conjur.net/reference/services/directory/variable Conjur Variable}.
28
- # See {Conjur::Variable} for operations on Conjur variables.
29
- #
30
- # ### Permissions
31
- # Any authenticated role may call this method
32
- #
33
- # @example Create a variable to store a database connection string
34
- # db_uri = "mysql://username:password@mysql.somehost.com/mydb"
35
- # var = api.create_variable 'text/plain', 'mysql-connection-string', id: 'production/mysql/uri'
36
- # var.add_value db_uri
37
- #
38
- # # Alternatively, we could have done this:
39
- # var = api.create_variable 'text/plain', 'mysql-connection-string',
40
- # id: 'production/mysql/uri',
41
- # value: db_uri
42
- #
43
- # @example Create a variable with a unique random id
44
- # var = api.create_variable 'text/plain', 'secret'
45
- # var.id # => 'kngeqg'
46
- #
47
- # @param [String] mime_type MIME type for the variable value, used to set the `"Content-Type"`header
48
- # when serving the variable's value. Must be non-empty.
49
- # @param [String] kind user defined `kind` for the variable. This is useful as a simple way to document
50
- # the variable's purpose. Must be non-empty
51
- # @param [Hash] options options for the new variable
52
- # @option options [String] :id specify an id for the new variable. Must be non-empty.
53
- # @option options [String] :value specify an initial value for the variable
54
- # @return [Conjur::Variable] an object representing the new variable
55
- # @raise [RestClient::Conflict] if you give an `:id` option and the variable already exists
56
- # @raise [RestClient::UnprocessableEntity] if `mime_type`, `kind`, or `options[:id]` is the empty string.
57
- def create_variable(mime_type, kind, options = {})
58
- standard_create Conjur::Core::API.host, :variable, nil, options.merge(mime_type: mime_type, kind: kind)
59
- end
60
-
61
- # Retrieve an object representing a {http://developer.conjur.net/reference/services/directory/variable Conjur Variable}.
62
- # The {Conjur::Variable} returned may or may not exist, and
63
- # your permissions on the corresponding resource determine the operations you can perform on it.
64
- #
65
- # ### Permissions
66
- # Any authenticated role can call this method.
67
- #
68
- # @param [String] id the unqualified id of the variable
69
- # @return [Conjur::Variable] and object representing the variable.
70
- def variable id
71
- standard_show Conjur::Core::API.host, :variable, id
72
- end
25
+
26
+ #@!group Variables
73
27
 
74
28
  # Fetch the values of a list of variables. This operation is more efficient than fetching the
75
29
  # values one by one.
@@ -79,56 +33,33 @@ module Conjur
79
33
  # * You have permission to `'execute'` all of the variables
80
34
  #
81
35
  # @example Fetch multiple variable values
82
- # values = variable_values ['postgres_uri', 'aws_secret_access_key', 'aws_access_key_id']
36
+ # values = variable_values ['myorg:variable:postgres_uri', 'myorg:variable:aws_secret_access_key', 'myorg:variable:aws_access_key_id']
83
37
  # values # =>
84
38
  # {
85
- # "postgres_uri" => "postgres://..."
86
- # "aws_secret_access_key" => "..."
87
- # "aws_access_key_id" => "..."
39
+ # "postgres://...",
40
+ # "the-secret-key",
41
+ # "the-access-key-id"
88
42
  # }
89
- #
43
+ #
90
44
  # This method is used to implement the {http://developer.conjur.net/reference/tools/utilities/conjurenv `conjur env`}
91
45
  # commands. You may consider using that instead to run your program in an environment with the necessary secrets.
92
46
  #
93
- # @param [Array<String>] varlist list of variable ids to fetch
94
- # @return [Hash] a hash mapping variable ids to variable values
47
+ # @param [Array<String>] variable_ids list of variable ids to fetch
48
+ # @return [Array<String>] a list of variable values corresponding to the variable ids.
95
49
  # @raise [RestClient::Forbidden, RestClient::ResourceNotFound] if any of the variables don't exist or aren't accessible.
96
- def variable_values(varlist)
97
- raise ArgumentError, "Variables list must be an array" unless varlist.kind_of? Array
98
- raise ArgumentError, "Variables list is empty" if varlist.empty?
99
- opts = "?vars=#{varlist.map { |v| fully_escape(v) }.join(',')}"
100
- begin
101
- resp = RestClient::Resource.new(Conjur::Core::API.host, self.credentials)['variables/values'+opts].get
102
- return JSON.parse( resp.body )
103
- rescue RestClient::ResourceNotFound
104
- return Hash[ *varlist.map { |v| [ v, variable(v).value ] }.flatten ]
105
- end
50
+ def variable_values variable_ids
51
+ raise ArgumentError, "Variables list must be an array" unless variable_ids.kind_of? Array
52
+ raise ArgumentError, "Variables list is empty" if variable_ids.empty?
53
+
54
+ opts = "?variable_ids=#{variable_ids.map { |v| fully_escape(v) }.join(',')}"
55
+
56
+ response =
57
+ RestClient::Resource.
58
+ new(Conjur.configuration.core_url,credentials)['secrets'+opts].get
59
+
60
+ return JSON.parse(response.body)
106
61
  end
107
-
108
- # Fetch all visible variables that expire within the given
109
- # interval (relative to the current time on the Conjur Server). If
110
- # no interval is specifed, all variables that are set to expire
111
- # will be returned.
112
- #
113
- # interval should either be a String containing an ISO8601
114
- # duration, or it should implement #to_i to return a number of
115
- # seconds.
116
- #
117
- # @example Use an ISO8601 duration to return variables expiring in the next month
118
- # expirations = api.variable_expirations('P1M')
119
- #
120
- # @example Use ActiveSupport to return variables expiring in the next month
121
- # require 'active_support/all'
122
- # expirations = api.variable_expirations(1.month)
123
-
124
- # param interval a String containing an ISO8601 duration , or a number of seconds
125
- # return [Hash] variable expirations that occur within the interval
126
- def variable_expirations(interval = nil)
127
- duration = interval.try { |i| i.respond_to?(:to_str) ? i : "PT#{i.to_i}S" }
128
- params = {}.tap { |p| p.merge!({:params => {:duration => duration }}) if duration }
129
- JSON.parse(RestClient::Resource.new(Conjur::Core::API.host, self.credentials)['variables/expirations'].get(params).body)
130
- end
131
-
62
+
132
63
  #@!endgroup
133
64
  end
134
65
  end
data/lib/conjur/api.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013 Conjur Inc
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,36 +21,36 @@
21
21
  require 'active_support'
22
22
  require 'active_support/deprecation'
23
23
 
24
- require 'conjur/cast'
25
24
  require 'conjur/configuration'
26
- require 'conjur/env'
25
+ require 'conjur/id'
27
26
  require 'conjur/base'
28
27
  require 'conjur/exceptions'
29
- require 'conjur/build_from_response'
28
+ require 'conjur/build_object'
29
+ require 'conjur/base_object'
30
30
  require 'conjur/acts_as_resource'
31
31
  require 'conjur/acts_as_role'
32
+ require 'conjur/acts_as_rolsource'
32
33
  require 'conjur/acts_as_user'
33
34
  require 'conjur/log_source'
34
35
  require 'conjur/has_attributes'
35
- require 'conjur/has_identifier'
36
- require 'conjur/has_id'
37
- require 'conjur/acts_as_asset'
38
- require 'conjur/authn-api'
39
- require 'conjur/authz-api'
40
- require 'conjur/audit-api'
41
- require 'conjur/core-api'
42
- require 'conjur/layer-api'
43
- require 'conjur/pubkeys-api'
44
- require 'conjur/host-factory-api'
45
- require 'conjur/bootstrap'
36
+ require 'conjur/api/authn'
37
+ require 'conjur/api/roles'
38
+ require 'conjur/api/resources'
39
+ require 'conjur/api/pubkeys'
40
+ require 'conjur/api/variables'
41
+ require 'conjur/api/policies'
42
+ require 'conjur/api/host_factories'
43
+ require 'conjur/host'
44
+ require 'conjur/group'
45
+ require 'conjur/variable'
46
+ require 'conjur/layer'
46
47
  require 'conjur/cache'
47
48
  require 'conjur-api/version'
48
- require 'conjur/api/info'
49
- require 'conjur/api/ldapsync'
50
49
 
51
50
  # Monkey patch RestClient::Request so it always uses
52
51
  # :ssl_cert_store. (RestClient::Resource uses Request to send
53
52
  # requests, so it sees :ssl_cert_store, too).
53
+ # @api private
54
54
  class RestClient::Request
55
55
  alias_method :initialize_without_defaults, :initialize
56
56
 
@@ -63,24 +63,12 @@ class RestClient::Request
63
63
  def initialize args
64
64
  initialize_without_defaults default_args.merge(args)
65
65
  end
66
-
67
66
  end
68
67
 
69
-
68
+ # @api private
70
69
  class RestClient::Resource
71
70
  include Conjur::Escape
72
71
  include Conjur::LogSource
73
- include Conjur::Cast
74
- extend Conjur::BuildFromResponse
75
-
76
- # @api private
77
- # @deprecated
78
- # The account used by the core service. This is deprecated in favor of {Conjur.account} and
79
- # {Conjur::Configuration#account}.
80
- # @return [String] the core account
81
- def core_conjur_account
82
- Conjur::Core::API.conjur_account
83
- end
84
72
 
85
73
  # @api private
86
74
  # This method exists so that all {RestClient::Resource}s support JSON serialization. It returns an
@@ -98,10 +86,7 @@ class RestClient::Resource
98
86
  #
99
87
  # @return {Conjur::API} the new api
100
88
  def conjur_api
101
- api = Conjur::API.new_from_token token, remote_ip
102
- api = api.with_privilege(conjur_privilege) if conjur_privilege
103
- api = api.with_audit_roles(audit_roles) if audit_roles
104
- api = api.with_audit_resources(audit_resources) if audit_resources
89
+ api = Conjur::API.new_from_token token, remote_ip: remote_ip
105
90
  api
106
91
  end
107
92
 
@@ -126,18 +111,6 @@ class RestClient::Resource
126
111
  options[:headers][:x_forwarded_for]
127
112
  end
128
113
 
129
- def conjur_privilege
130
- options[:headers][:x_conjur_privilege]
131
- end
132
-
133
- def audit_roles
134
- options[:headers][:conjur_audit_roles].try { |r| Conjur::API.decode_audit_ids(r) }
135
- end
136
-
137
- def audit_resources
138
- options[:headers][:conjur_audit_resources].try { |r| Conjur::API.decode_audit_ids(r) }
139
- end
140
-
141
114
  # The username this resource authenticates as.
142
115
  #
143
116
  # @return [String] the username