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
@@ -0,0 +1,67 @@
1
+ Feature: Work with Variable values.
2
+
3
+ Background:
4
+ Given I run the code:
5
+ """
6
+ @variable_id = "password"
7
+ $conjur.load_policy 'root', <<-POLICY
8
+ - !variable #{@variable_id}
9
+ - !variable #{@variable_id}-2
10
+ POLICY
11
+ @variable = $conjur.resource("cucumber:variable:#{@variable_id}")
12
+ @variable_2 = $conjur.resource("cucumber:variable:#{@variable_id}-2")
13
+ """
14
+
15
+ Scenario: Initially the variable has no values
16
+ When I run the code:
17
+ """
18
+ @variable.version_count
19
+ """
20
+ Then the result should be "0"
21
+
22
+ Scenario: Add a value, retrieve the variable metadata and the value.
23
+ Given I run the code:
24
+ """
25
+ @variable.add_value 'value-0'
26
+ """
27
+ When I run the code:
28
+ """
29
+ @variable.version_count
30
+ """
31
+ Then the result should be "1"
32
+ And I run the code:
33
+ """
34
+ @variable.value
35
+ """
36
+ Then the result should be "value-0"
37
+
38
+ Scenario: Retrieve a historical value.
39
+ Given I run the code:
40
+ """
41
+ @variable.add_value 'value-0'
42
+ @variable.add_value 'value-1'
43
+ @variable.add_value 'value-2'
44
+ """
45
+ When I run the code:
46
+ """
47
+ @variable.value(1)
48
+ """
49
+ Then the result should be "value-0"
50
+
51
+ Scenario: Retrieve multiple values in a batch
52
+ Given I run the code:
53
+ """
54
+ @variable.add_value 'value-0'
55
+ @variable_2.add_value 'value-2'
56
+ """
57
+ When I run the code:
58
+ """
59
+ $conjur.variable_values([ @variable, @variable_2 ].map(&:id))
60
+ """
61
+ Then the JSON should be:
62
+ """
63
+ {
64
+ "cucumber:variable:password": "value-0",
65
+ "cucumber:variable:password-2": "value-2"
66
+ }
67
+ """
@@ -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,89 +19,119 @@
19
19
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  #
21
21
 
22
- require 'active_support/dependencies/autoload'
23
- require 'active_support/core_ext'
24
-
25
22
  module Conjur
26
-
27
- # This module is included in asset classes that have an associated resource.
23
+ # This module is included in object classes that have resource behavior.
28
24
  module ActsAsResource
29
- # Return the {Conjur::Resource} associated with this asset.
30
- #
31
- # @return [Conjur::Resource] the resource associated with this asset
32
- def resource
33
- require 'conjur/resource'
34
- # NOTE: should we use specific class to build sub-url below?
35
- Conjur::Resource.new(Conjur::Authz::API.host, self.options)[[ core_conjur_account, 'resources', path_escape(resource_kind), path_escape(resource_id) ].join('/')]
25
+ # @api private
26
+ def self.included(base)
27
+ base.include HasAttributes
28
+ base.include Escape
29
+ base.extend QueryString
36
30
  end
37
31
 
38
- # Return the *qualified* id of the resource associated with this asset.
32
+ # The full role id of the role that owns this resource.
39
33
  #
40
- # @return [String] the qualified id of the resource associated with this asset.
41
- def resourceid
42
- [ core_conjur_account, resource_kind, resource_id ].join(':')
43
- end
44
-
45
- # The kind of resource underlying the asset. The kind is the second token in
46
- # a Conjur id like `"account:kind:id"`.
34
+ # @example
35
+ # api.current_role # => 'conjur:user:jon'
36
+ # resource = api.create_resource 'conjur:example:resource-owner'
37
+ # resource.owner # => 'conjur:user:jon'
47
38
  #
48
- # @see Conjur:Resource#kind
49
- # @return [String] the resource kind for the underlying resource
50
- def resource_kind
51
- self.class.name.split("::")[-1].underscore.split('/').join('-')
39
+ # @return [String] the full role id of this resource's owner.
40
+ def owner
41
+ build_object attributes['owner'], default_class: Role
52
42
  end
53
43
 
54
- # @api private
44
+ # Check whether this object exists by performing a HEAD request to its URL.
55
45
  #
56
- # Confusingly, this method returns the *unqualified* resource id, as opposed to the *qualified*
57
- # resource id returned by {#resourceid}.
46
+ # This method will return false if the object doesn't exist.
58
47
  #
59
- # @return [String] the *unqualified* resource id.
60
- def resource_id
61
- id
62
- end
63
-
64
- # @api private
65
- # Delete a resource
66
- # This doesn't typically work ;-)
67
- # @return [void]
68
- def delete
69
- resource.delete
70
- super
48
+ # @example
49
+ # does_not_exist = api.user 'does-not-exist' # This returns without error.
50
+ #
51
+ # # this is wrong!
52
+ # owner = does_not_exist.owner # raises RestClient::ResourceNotFound
53
+ #
54
+ # # this is right!
55
+ # owner = if does_not_exist.exists?
56
+ # does_not_exist.owner
57
+ # else
58
+ # nil # or some sensible default
59
+ # end
60
+ #
61
+ # @return [Boolean] does it exist?
62
+ def exists?
63
+ begin
64
+ rbac_resource_resource.head
65
+ true
66
+ rescue RestClient::Forbidden
67
+ true
68
+ rescue RestClient::ResourceNotFound
69
+ false
70
+ end
71
71
  end
72
72
 
73
- # Permit `role` to perform `privilege` on this resource. A
74
- # {http://developer.conjur.net/reference/services/authorization/permission.html permission} represents an ability
75
- # to perform certain (application defined) actions on this resource.
73
+ # Lists roles that have a specified privilege on the resource.
74
+ #
75
+ # This will return only roles of which api.current_user is a member.
76
76
  #
77
- # This method is equivalent to calling `resource.permit`.
77
+ # Options:
78
78
  #
79
- # @example Allow a group and its members to get the value of a Conjur variable
80
- # group = api.group 'some-project/developers'
81
- # variable = api.variable 'some-project/development/postgres-uri'
82
- # variable.permit 'execute', group
79
+ # * **offset** Zero-based offset into the result set.
80
+ # * **limit** Total number of records returned.
83
81
  #
84
- # @see Conjur::Resource#permit
85
- # @param [String] privilege the privilege to grant
86
- # @param [String, #roleid] role the role to which the privilege is granted
87
- # @param options [Hash, nil] options to pass through to `RestClient::Resource#post`
88
- # @return [void]
89
- # @raise [RestClient::Forbidden] if you don't have permission to perform this operation.
90
- def permit(privilege, role, options = {})
91
- resource.permit privilege, role, options
82
+ # @example
83
+ # resource = api.resource 'conjur:variable:example'
84
+ # resource.permitted_roles 'execute' # => ['conjur:user:admin']
85
+ # # After permitting 'execute' to user 'jon'
86
+ # resource.permitted_roles 'execute' # => ['conjur:user:admin', 'conjur:user:jon']
87
+ #
88
+ # @param privilege [String] the privilege
89
+ # @return [Array<String>] the ids of roles that have `privilege` on this resource.
90
+ def permitted_roles privilege
91
+ options = {}
92
+ options[:permitted_roles] = true
93
+ options[:privilege] = privilege
94
+ result = JSON.parse rbac_resource_resource[options_querystring options].get
95
+ if result.is_a?(Hash) && ( count = result['count'] )
96
+ count
97
+ else
98
+ result
99
+ end
92
100
  end
93
101
 
94
-
95
- # Deny `role` permission to perform actions corresponding to `privilege` on the underlying resource.
102
+ # True if the logged-in role, or a role specified using the :role option, has the
103
+ # specified +privilege+ on this resource.
96
104
  #
97
- # @see Conjur::Resource#deny
98
- # @param privilege [String, #each] A permission name or an `Enumerable` of permissions to deny. In the
99
- # later, all permissions will be denied.
100
- # @param role [String, :roleid] A full role id or a role-ish object whose permissions we will deny.
105
+ # @example
106
+ # api.current_role # => 'conjur:cat:mouse'
107
+ # resource.permitted_roles 'execute' # => ['conjur:user:admin', 'conjur:cat:mouse']
108
+ # resource.permitted_roles 'update', # => ['conjur:user:admin', 'conjur:cat:gino']
101
109
  #
102
- # @return [void]
103
- def deny(privilege, role)
104
- resource.deny privilege, role
110
+ # resource.permitted? 'update' # => false, `mouse` can't update this resource
111
+ # resource.permitted? 'execute' # => true, `mouse` can execute it.
112
+ # resource.permitted? 'update', role: 'conjur:cat:gino' # => true, `gino` can update it.
113
+ # @param privilege [String] the privilege to check
114
+ # @param role [String,nil] :role check whether the role given by this full role id is permitted
115
+ # instead of checking +api.current_role+.
116
+ # @return [Boolean]
117
+ def permitted? privilege, role: nil
118
+ options = {}
119
+ options[:check] = true
120
+ options[:privilege] = privilege
121
+ options[:role] = cast_to_id(role) if role
122
+ rbac_resource_resource[options_querystring options].get
123
+ true
124
+ rescue RestClient::Forbidden
125
+ false
126
+ rescue RestClient::ResourceNotFound
127
+ false
128
+ end
129
+
130
+ private
131
+
132
+ # RestClient::Resource for RBAC resource operations.
133
+ def rbac_resource_resource
134
+ RestClient::Resource.new(Conjur.configuration.core_url, credentials)['resources'][id.to_url_path]
105
135
  end
106
136
  end
107
137
  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
@@ -29,69 +29,120 @@ module Conjur
29
29
  # The {Conjur::ActsAsRole} module itself should be considered private, but it's methods are
30
30
  # public when added to a Conjur asset class.
31
31
  module ActsAsRole
32
-
33
- # The qualified identifier for the role associated with this asset. A *qualified* identifier
34
- # prepends the asset's account and kind, for example, a {Conjur::User} with login `'bob'` in a
35
- # system with organizational account `'conjur'` would have a `roleid` of `'conjur:user:bob'`
36
- #
37
- # @return [String] the qualified role id
38
- def roleid
39
- [ core_conjur_account, role_kind, id ].join(':')
32
+
33
+ # Login name of the role. This is formed from the role kind and role id.
34
+ # For users, the role kind can be omitted.
35
+ def login
36
+ [ kind, identifier ].delete_if{|t| t == "user"}.join('/')
40
37
  end
41
- alias role_id roleid
42
38
 
43
- # The `kind` of a role. This may be any value, but standard ones correspond to various high level
44
- # Conjur assets, for example, `'user'`, `'group'`, or `'variable'`.
39
+ # Check whether this object exists by performing a HEAD request to its URL.
45
40
  #
46
- # Note that this method derives the role kind from the asset's class name.
41
+ # This method will return false if the object doesn't exist.
47
42
  #
48
- # @return [String] the role kind
49
- def role_kind
50
- self.class.name.split('::')[-1].underscore
51
- end
52
-
53
- # Get a {Conjur::Role} instance corresponding to the `role` associated with this asset.
54
- def role
55
- require 'conjur/role'
56
- Conjur::Role.new(Conjur::Authz::API.host, self.options)[Conjur::API.parse_role_id(self.roleid).join('/')]
43
+ # @example
44
+ # does_not_exist = api.user 'does-not-exist' # This returns without error.
45
+ #
46
+ # # this is wrong!
47
+ # owner = does_not_exist.members # raises RestClient::ResourceNotFound
48
+ #
49
+ # # this is right!
50
+ # owner = if does_not_exist.exists?
51
+ # does_not_exist.members
52
+ # else
53
+ # nil # or some sensible default
54
+ # end
55
+ #
56
+ # @return [Boolean] does it exist?
57
+ def exists?
58
+ begin
59
+ rbac_role_resource.head
60
+ true
61
+ rescue RestClient::Forbidden
62
+ true
63
+ rescue RestClient::ResourceNotFound
64
+ false
65
+ end
57
66
  end
58
67
 
59
- # Permit the asset to perform `privilege` on `resource`. You can also use this method to control whether the role
60
- # is able to grant the privilege on the resource to other roles by passing a `:grant_option` option.
61
- #
62
- # This method is primarily intended for use in the
63
- # {http://developer.conjur.net/reference/tools/utilities/policy-load.html Conjur Policy DSL},
64
- # and simply delegates to {Conjur::Resource#permit}. For code clarity, you might consider using
65
- # that method instead.
68
+ # Find all roles of which this role is a member. By default, role relationships are recursively expanded,
69
+ # so if `a` is a member of `b`, and `b` is a member of `c`, `a.all` will include `c`.
66
70
  #
67
71
  # ### Permissions
72
+ # You must be a member of the role to call this method.
68
73
  #
69
- # To call this method, you must *own* the resource, or have the privilege on it with grant option set to true.
74
+ # You can restrict the roles returned to one or more role ids. This feature is mainly useful
75
+ # for checking whether this role is a member of any of a set of roles.
70
76
  #
71
- # @api dsl
72
- # @param [String] privilege the privilege to allow this role to perform, e.g. `'execute'` or `'update'`
73
- # @param [Conjur::Resource, #resource_id, String] resource the resource to grant `privilege` on.
74
- # @param [Hash] options Options to pass through to RestClient::Resource#post
75
- # @option options [Boolean] :grant_option whether this role will be able to grant the privilege to other roles.
76
- # @return [void]
77
- def can(privilege, resource, options = {})
78
- require 'conjur/resource'
79
- Conjur::Resource.new(Conjur::Authz::API.host, self.options)[Conjur::API.parse_resource_id(resource).join('/')].permit privilege, self.roleid, options
80
- end
81
-
82
- # Deny the asset's role the ability to perform `privilege` on `resource`. This operation is the inverse of {#can}.
77
+ # ### Options
83
78
  #
84
- # This method is primarily intended for use in the
85
- # {http://developer.conjur.net/reference/tools/utilities/policy-load.html Conjur Policy DSL},
86
- # and simply delegates to {Conjur::Resource#permit}. For code clarity, you might consider using
87
- # that method instead.
79
+ # * **recursive** Defaults to +true+, performs recursive expansion of the memberships.
88
80
  #
89
- # @see Conjur::Resource#deny
81
+ # @example Show all roles of which `"conjur:group:pubkeys-1.0/key-managers"` is a member
82
+ # # Add alice to the group, so we see something interesting
83
+ # key_managers = api.group('pubkeys-1.0/key-managers')
84
+ # key_managers.add_member api.user('alice')
90
85
  #
91
- # @api dsl
92
- def cannot(privilege, resource, options = {})
93
- require 'conjur/resource'
94
- Conjur::Resource.new(Conjur::Authz::API.host, self.options)[Conjur::API.parse_resource_id(resource).join('/')].deny privilege, self.roleid
86
+ # # Show the memberships, mapped to the member ids.
87
+ # key_managers.role.all.map(&:id)
88
+ # # => ["conjur:group:pubkeys-1.0/admin", "conjur:user:alice"]
89
+ #
90
+ # @example See if role `"conjur:user:alice"` is a member of either `"conjur:groups:developers"` or `"conjur:group:ops"`
91
+ # is_member = api.role('conjur:user:alice').all(filter: ['conjur:group:developers', 'conjur:group:ops']).any?
92
+ #
93
+ # @param [Hash] options options for the request
94
+ # @return [Array<Conjur::Role>] Roles of which this role is a member
95
+ def memberships options = {}
96
+ request = if options.delete(:recursive) == false
97
+ options["memberships"] = true
98
+ else
99
+ options["all"] = true
100
+ end
101
+ if filter = options.delete(:filter)
102
+ filter = [filter] unless filter.is_a?(Array)
103
+ options["filter"] = filter.map{ |obj| cast_to_id(obj) }
104
+ end
105
+
106
+ result = JSON.parse(rbac_role_resource[options_querystring options].get)
107
+ if result.is_a?(Hash) && ( count = result['count'] )
108
+ count
109
+ else
110
+ host = Conjur.configuration.core_url
111
+ result.collect do |item|
112
+ if item.is_a?(String)
113
+ build_object(item, default_class: Role)
114
+ else
115
+ RoleGrant.parse_from_json(item, self.options)
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ # Fetch the direct members of this role. The results are *not* recursively expanded).
122
+ #
123
+ # ### Permissions
124
+ # You must be a member of the role to call this method.
125
+ #
126
+ # @param options [Hash, nil] extra parameters to pass to the webservice method.
127
+ # @return [Array<Conjur::RoleGrant>] the role memberships
128
+ # @raise [RestClient::Forbidden] if you don't have permission to perform this operation
129
+ def members options = {}
130
+ options["members"] = true
131
+ result = JSON.parse(rbac_role_resource[options_querystring options].get)
132
+ if result.is_a?(Hash) && ( count = result['count'] )
133
+ count
134
+ else
135
+ result['members'].collect do |json|
136
+ RoleGrant.parse_from_json(json, credentials)
137
+ end
138
+ end
139
+ end
140
+
141
+ private
142
+
143
+ # RestClient::Resource for RBAC role operations.
144
+ def rbac_role_resource
145
+ RestClient::Resource.new(Conjur.configuration.core_url, credentials)['roles'][id.to_url_path]
95
146
  end
96
147
  end
97
148
  end
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013 Conjur Inc
2
+ # Copyright (C) 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
@@ -18,19 +18,15 @@
18
18
  # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
19
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  #
21
-
22
21
  module Conjur
23
- module Audit
24
- class API < Conjur::API
25
- class << self
26
- # The URL for the audit service
27
- #
28
- # @return [String] the audit service url.
29
- def host
30
- Conjur.configuration.audit_url
31
- end
32
- end
22
+
23
+ # This module provides methods for things that have an associated {Conjur::Role} and
24
+ # {Conjur::Resource}.
25
+ module ActsAsRolsource
26
+ # @api private
27
+ def self.included(base)
28
+ base.include ActsAsRole
29
+ base.include ActsAsResource
33
30
  end
34
31
  end
35
- end
36
- require 'conjur/api/audit'
32
+ end
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2013-2015 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,17 +22,20 @@ module Conjur
22
22
  # This module provides methods for things that are like users (specifically, those that have
23
23
  # api keys).
24
24
  module ActsAsUser
25
- include ActsAsRole
25
+ # @api private
26
+ def self.included(base)
27
+ base.include ActsAsRolsource
28
+ end
26
29
 
27
30
  # Returns a newly created user's api_key.
28
31
  #
29
- # @note this method can only be called on newly created user-like things (those returned from, for example,)
30
- # {Conjur::API#create_user}.
32
+ # @note The API key is not returned by {API#resource}. It is only available
33
+ # via {API#login}, when the object is newly created, and when the API key is rotated.
31
34
  #
32
35
  # @return [String] the api key
33
36
  # @raise [Exception] when the object isn't newly created.
34
37
  def api_key
35
- attributes['api_key'] or raise "api_key is only available on a newly created #{self.class.name.downcase}"
38
+ attributes['api_key'] or raise "api_key is only available on a newly created #{kind}"
36
39
  end
37
40
 
38
41
  # Create an api logged in as this user-like thing.
@@ -41,34 +44,22 @@ module Conjur
41
44
  # @see #api_key
42
45
  # @return [Conjur::API] an api logged in as this user-like thing.
43
46
  def api
44
- Conjur::API.new_from_key login, api_key
47
+ Conjur::API.new_from_key login, api_key, account: account
45
48
  end
46
49
 
47
- # Rotate this user's API key. You must have `update` permission on the user to do so.
50
+ # Rotate this role's API key. You must have `update` permission on the user to do so.
48
51
  #
49
52
  # @note You will not be able to access the API key returned by this method later, so you should
50
53
  # probably hang onto it it.
51
54
  #
52
- # @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`
53
56
  #
54
57
  # @note This feature requires a Conjur appliance running version 4.6 or higher.
55
58
  #
56
59
  # @return [String] the new API key for this user.
57
60
  def rotate_api_key
58
- path = "users/api_key?id=#{fully_escape login}"
59
- RestClient::Resource.new(Conjur::Authn::API.host, options)[path].put('').body
60
- end
61
-
62
- # Set login network restrictions for the user.
63
- #
64
- # @param [Array<String, IPAddr>] networks which allow logging in. Set to empty to remove restrictions
65
- def set_cidr_restrictions networks
66
- authn_user = RestClient::Resource.new(Conjur::Authn::API.host, options)\
67
- ["users?id=#{fully_escape login}"]
68
-
69
- # we need use JSON here to be able to PUT an empty array
70
- params = { cidr: [*networks].map(&CIDR.method(:validate)).map(&:to_s) }
71
- authn_user.put params.to_json, content_type: :json
61
+ path = "authn/#{path_escape account}/api_key?role=#{id}"
62
+ core_resource[path].put('').body
72
63
  end
73
64
  end
74
65
  end