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
@@ -23,18 +23,16 @@ require 'conjur/user'
23
23
  module Conjur
24
24
  class API
25
25
  class << self
26
- #@!group Authentication Methods
26
+ #@!group Authentication
27
27
 
28
- # The Conjur {http://developer.conjur.net/reference/services/authentication/login.html login}
29
- # operation exchanges a username and a password for an api key. The api key
28
+ # Exchanges a username and a password for an api key. The api key
30
29
  # is preferable for storage and use in code, as it can be rotated and has far greater entropy than
31
30
  # a user memorizable password.
32
31
  #
33
- # * Note that this method works only for {http://developer.conjur.net/reference/services/directory/user Users}. While
34
- # {http://developer.conjur.net/reference/services/directory/hosts Hosts} possess Conjur identities, they do not
35
- # have passwords.
36
- # * If you pass an api key to this method instead of a password, it will simply return the API key.
37
- # * This method uses Basic Auth to send the credentials.
32
+ # * Note that this method works only for {Conjur::User}s. While
33
+ # {Conjur::Host}s are roles, they do not have passwords.
34
+ # * If you pass an api key to this method instead of a password, it will verify and return the API key.
35
+ # * This method uses HTTP Basic Authentication to send the credentials.
38
36
  #
39
37
  # @example
40
38
  # bob_api_key = Conjur::API.login('bob', 'bob_password')
@@ -43,104 +41,71 @@ module Conjur
43
41
  # @param [String] username The `username` or `login` for the
44
42
  # {http://developer.conjur.net/reference/services/directory/user Conjur User}.
45
43
  # @param [String] password The `password` or `api key` to authenticate with.
44
+ # @param [String] account The organization account.
46
45
  # @return [String] the API key.
47
- # @raise [RestClient::Exception] when the request fails or the identity provided is invalid.
48
- def login username, password
46
+ def login username, password, account: Conjur.configuration.account
49
47
  if Conjur.log
50
- Conjur.log << "Logging in #{username} via Basic authentication\n"
48
+ Conjur.log << "Logging in #{username} to account #{account} via Basic authentication\n"
51
49
  end
52
- RestClient::Resource.new(Conjur::Authn::API.host, user: username, password: password)['users/login'].get
50
+ RestClient::Resource.new(Conjur.configuration.authn_url, user: username, password: password)[fully_escape account]['login'].get
53
51
  end
54
52
 
55
- # TODO I have NO idea how to document login_cas!
56
-
57
- # This method logs in via CAS. It is similar to the {.login} method, the only difference being that
58
- # you need a `cas_api_url`, provided by the administrator of your `CAS` service.
59
- #
60
- # @see .login
61
- # @param [String] username the Conjur username
62
- # @param [String] password the Conjur password
63
- # @param [String] cas_api_url the url of the CAS service
64
- # @return [String] a `CAS` ticket
65
- def login_cas username, password, cas_api_url
66
- if Conjur.log
67
- Conjur.log << "Logging in #{username} via CAS authentication\n"
68
- end
69
- require 'cas_rest_client'
70
- client = CasRestClient.new(:username => username, :password => password, :uri => [ cas_api_url, 'v1', 'tickets' ].join('/'), :use_cookies => false)
71
- client.get("#{Conjur::Authn::API.host}/users/login").body
72
- end
73
-
74
- # The Conjur {http://developer.conjur.net/reference/services/authentication/authenticate.html authenticate} operation
75
- # exchanges Conjur credentials for a token. The token can then be used to authenticate further API calls.
76
- #
77
- # You will generally not need to use this method, as the API manages tokens automatically for you.
53
+ # Exchanges Conjur the API key (refresh token) for an access token. The access token can
54
+ # then be used to authenticate further API calls.
78
55
  #
79
56
  # @param [String] username The username or host id for which we want a token
80
- # @param [String] password The password or api key
57
+ # @param [String] api_key The api key
58
+ # @param [String] account The organization account.
81
59
  # @return [String] A JSON formatted authentication token.
82
- def authenticate username, password
60
+ def authenticate username, api_key, account: Conjur.configuration.account
61
+ account ||= Conjur.configuration.account
83
62
  if Conjur.log
84
- Conjur.log << "Authenticating #{username}\n"
63
+ Conjur.log << "Authenticating #{username} to account #{account}\n"
85
64
  end
86
- JSON::parse(RestClient::Resource.new(Conjur::Authn::API.host)["users/#{fully_escape username}/authenticate"].post password, content_type: 'text/plain')
65
+ JSON::parse(RestClient::Resource.new(Conjur.configuration.authn_url)[fully_escape account][fully_escape username]['authenticate'].post api_key, content_type: 'text/plain')
87
66
  end
88
67
 
89
-
90
68
  # Change a user's password. To do this, you must have the user's current password. This does not change or rotate
91
- # api keys. However, you *can* use the user's api key as the *current* password, if the user was not created
69
+ # api keys. However, you *can* use the user's api key as the *current* password, if the user was not created
92
70
  # with a password.
93
71
  #
94
- # @param [String] username the name of the user whose password we want to change
95
- # @param [String] password the user's *current* password *or* api key
72
+ # @param [String] username the name of the user whose password we want to change.
73
+ # @param [String] password the user's *current* password *or* api key.
96
74
  # @param [String] new_password the new password for the user.
75
+ # @param [String] account The organization account.
97
76
  # @return [void]
98
- def update_password username, password, new_password
77
+ def update_password username, password, new_password, account: Conjur.configuration.account
99
78
  if Conjur.log
100
- Conjur.log << "Updating password for #{username}\n"
79
+ Conjur.log << "Updating password for #{username} in account #{account}\n"
101
80
  end
102
- RestClient::Resource.new(Conjur::Authn::API.host, user: username, password: password)['users/password'].put new_password
81
+ RestClient::Resource.new(Conjur.configuration.authn_url, user: username, password: password)[fully_escape account]['password'].put new_password
103
82
  end
104
83
 
105
84
  #@!endgroup
106
85
 
107
86
  #@!group Password and API key management
108
87
 
109
- # Rotate the currently authenticated user's API key by generating and returning a new one.
110
- # The old API key is no longer valid after calling this method. You must have the user's current
111
- # API key or password to perform this operation. This method *does not* affect the user's password.
112
- #
113
- # @note If the user does not have a password, the returned API key will be the **only** way to authenticate as
114
- # the user. Therefore, you'd best save it.
115
- #
116
- # @note This feature requires version 4.6 of the Conjur appliance.
88
+ # Rotate the currently authenticated user or host API key by generating and returning a new one.
89
+ # The old API key is no longer valid after calling this method. You must have the current
90
+ # API key or password to perform this operation. This method *does not* affect a user's password.
117
91
  #
118
- # @param [String] username the name of the user whose password we want to change
119
- # @param [String] password the user's current password *or* api key
120
- # @return [String] the new API key for the user
121
- def rotate_api_key username, password
92
+ # @param [String] username the name of the user or host whose API key we want to change
93
+ # @param [String] password the user's current api key
94
+ # @param [String] account The organization account.
95
+ # @return [String] the new API key
96
+ def rotate_api_key username, password, account: Conjur.configuration.account
122
97
  if Conjur.log
123
- Conjur.log << "Rotating API key for self (#{username})\n"
98
+ Conjur.log << "Rotating API key for self (#{username} in account #{account})\n"
124
99
  end
125
100
 
126
101
  RestClient::Resource.new(
127
- Conjur::Authn::API.host,
102
+ Conjur.configuration.authn_url,
128
103
  user: username,
129
104
  password: password
130
- )['users/api_key'].put('').body
105
+ )[fully_escape account]['api_key'].put('').body
131
106
  end
132
107
 
133
108
  #@!endgroup
134
109
  end
135
-
136
- # @api private
137
- # This is used internally to create a user that we can log in as without creating
138
- # an actual user in the directory, as with #create_user.
139
- def create_authn_user login, options = {}
140
- log do |logger|
141
- logger << "Creating authn user #{login}"
142
- end
143
- JSON.parse RestClient::Resource.new(Conjur::Authn::API.host, credentials)['users'].post(options.merge(login: login))
144
- end
145
110
  end
146
111
  end
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (C) 2014 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,72 +22,52 @@ require 'conjur/host_factory'
22
22
 
23
23
  module Conjur
24
24
  class API
25
+ #@!group Host Factory
26
+
25
27
  class << self
26
- # Creates a host and returns the response Hash.
28
+ # Use a host factory token to create a new host. Unlike most other methods, this
29
+ # method does not require a Conjur access token. The host factory token is the
30
+ # authentication and authorization to create the host.
31
+ #
32
+ # The token must be valid. The host id can be a new host, or an existing host.
33
+ # If the host already exists, the server verifies that its layer memberships
34
+ # match the host factory exactly. Then, its API key is rotated and returned with
35
+ # the response.
36
+ #
37
+ # @param [String] token the host factory token.
38
+ # @param [String] id the id of a new or existing host.
39
+ # @param options [Hash] additional host creation options.
40
+ # @return [Host]
27
41
  def host_factory_create_host token, id, options = {}
28
42
  token = token.token if token.is_a?(HostFactoryToken)
29
43
  http_options = {
30
44
  headers: { authorization: %Q(Token token="#{token}") }
31
45
  }
32
- response = RestClient::Resource.new(Conjur::API.host_factory_asset_host, http_options)["hosts"].post(options.merge(id: id)).body
33
- JSON.parse(response)
34
- end
35
- end
36
-
37
- # Options:
38
- # +layers+ list of host factory layers
39
- # +roleid+ host factory role id
40
- # +role+ host factory role. If this is provided, it is converted to roleid.
41
- def create_host_factory(id, options = {})
42
- if options[:layers]
43
- options[:layers] = options[:layers].map do |layer|
44
- if layer.is_a?(Conjur::Layer)
45
- layer.id
46
- elsif layer.is_a?(String)
47
- layer
48
- else
49
- raise "Can't interpret layer #{layer}"
50
- end
46
+ response = RestClient::Resource.new(Conjur.configuration.core_url, http_options)["host_factories"]["hosts"].post(options.merge(id: id)).body
47
+ attributes = JSON.parse(response)
48
+ Host.new(attributes['id'], {}).tap do |host|
49
+ host.attributes = attributes
51
50
  end
52
51
  end
53
- if role = options.delete(:role)
54
- options[:roleid] = role.roleid
52
+
53
+ # Revokes a host factory token. After revocation, the token can no longer be used to
54
+ # create hosts.
55
+ #
56
+ # @param [Hash] credentials authentication credentials of the current user.
57
+ # @param [String] token the host factory token.
58
+ def revoke_host_factory_token credentials, token
59
+ RestClient::Resource.new(Conjur.configuration.core_url, credentials)['host_factory_tokens'][token].delete
55
60
  end
56
- log do |logger|
57
- logger << "Creating host_factory #{id}"
58
- unless options.blank?
59
- logger << " with options #{options.to_json}"
60
- end
61
- end
62
- options ||= {}
63
- options[:id] = id
64
- resp = RestClient::Resource.new(Conjur::API.host_factory_asset_host, credentials).post(options)
65
- Conjur::HostFactory.build_from_response(resp, credentials)
66
61
  end
67
62
 
68
- def host_factory id
69
- Conjur::HostFactory.new(Conjur::API.host_factory_asset_host, credentials)[fully_escape(id)]
70
- end
71
-
63
+ # Revokes a host factory token. After revocation, the token can no longer be used to
64
+ # create hosts.
65
+ #
66
+ # @param [String] token the host factory token.
72
67
  def revoke_host_factory_token token
73
- token = token.token if token.is_a?(Conjur::HostFactoryToken)
74
- RestClient::Resource.new(Conjur::API.host_factory_asset_host, credentials)["tokens/#{token}"].delete
75
- end
76
-
77
- def show_host_factory_token token
78
- token = token.token if token.is_a?(Conjur::HostFactoryToken)
79
- attrs = JSON.parse(RestClient::Resource.new(Conjur::API.host_factory_asset_host, credentials)["tokens/#{token}"].get.body)
80
- Conjur::HostFactoryToken.new(Conjur::API.host_factory_asset_host, credentials)["tokens"][attrs['token']].tap do |token|
81
- token.attributes = attrs
82
- end
83
- end
84
-
85
- # Creates a Host and returns a Host object.
86
- def host_factory_create_host token, id, options = {}
87
- attributes = self.class.host_factory_create_host token, id, options
88
- Conjur::Host.new(Conjur::API.core_asset_host, credentials)["hosts"][fully_escape attributes['id']].tap do |host|
89
- host.attributes = attributes
90
- end
68
+ self.class.revoke_host_factory_token credentials, token
91
69
  end
70
+
71
+ #@!endgroup
92
72
  end
93
73
  end
@@ -0,0 +1,56 @@
1
+ #
2
+ # Copyright 2013-2017 Conjur Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+ require 'conjur/policy_load_result'
22
+ require 'conjur/policy'
23
+
24
+ module Conjur
25
+ class API
26
+ #@!group Policy management
27
+
28
+ # Append only.
29
+ POLICY_METHOD_POST = :post
30
+ # Allow explicit deletion statements, but don't delete implicitly delete data.
31
+ POLICY_METHOD_PATCH = :patch
32
+ # Replace the policy entirely, deleting any existing data that is not declared in the new policy.
33
+ POLICY_METHOD_PUT = :put
34
+
35
+ # Load a policy document into the server.
36
+ #
37
+ # The modes are support for policy loading:
38
+ #
39
+ # * POLICY_METHOD_POST Policy data will be added to the named policy. Deletions are not allowed.
40
+ # * POLICY_METHOD_PATCH Policy data can be added to or deleted from the named policy. Deletions
41
+ # are performed by an explicit `!delete` statement.
42
+ # * POLICY_METHOD_PUT The policy completely replaces the name policy. Policy data which is present
43
+ # in the server, but not present in the new policy definition, is deleted.
44
+ #
45
+ # @param id [String] id of the policy to load.
46
+ # @param policy [String] YAML-formatted policy definition.
47
+ # @param account [String] Conjur organization account
48
+ # @param method [Symbol] Policy load method to use: {POLICY_METHOD_POST} (default), {POLICY_METHOD_PATCH}, or {POLICY_METHOD_PUT}.
49
+ def load_policy id, policy, account: Conjur.configuration.account, method: POLICY_METHOD_POST
50
+ request = RestClient::Resource.new(Conjur.configuration.core_url, credentials)['policies'][path_escape account]['policy'][path_escape id]
51
+ PolicyLoadResult.new JSON.parse(request.send(method, policy))
52
+ end
53
+
54
+ #@!endgroup
55
+ end
56
+ end
@@ -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,165 +21,41 @@
21
21
 
22
22
  module Conjur
23
23
 
24
- class API
25
- # @!group Public Keys Service
26
-
27
- # Fetch *all* public keys for the user. This method returns a newline delimited
28
- # String for compatibility with the authorized_keys SSH format.
29
- #
30
- #
31
- # If the given user does not exist, an empty String will be returned. This is to prevent attackers from determining whether
32
- # a user exists.
33
- #
34
- # ## Permissions
35
- # You do not need any special permissions to call this method, since public keys are, well, public.
36
- #
37
- #
38
- # @example
39
- # puts api.public_keys('jon')
40
- # # ssh-rsa [big long string] jon@albert
41
- # # ssh-rsa [big long string] jon@conjurops
42
- #
43
- # @param [String] username the *unqualified* Conjur username
44
- # @return [String] newline delimited public keys
45
- def public_keys username
46
- public_keys_resource(username).get
47
- end
48
-
49
-
50
- # Fetch a specific key by name. The key name is the last token in the public key itself,
51
- # typically formatted as `'<login>@<hostname>'`.
52
- #
53
- # ## Permissions
54
- # You do not need any special permissions to call this method, since public keys are, well, public.
55
- #
56
- # @example Get bob's key for 'bob@somehost'
57
- # key = begin
58
- # api.public_key 'bob', 'bob@somehost'
59
- # rescue RestClient::ResourceNotFound
60
- # puts "Key or user not found!"
61
- # # Deal with it
62
- # end
63
- #
64
- #
65
- # @param [String] username A Conjur username
66
- # @param [String] keyname The name or identifier of the key
67
- # @return [String] the public key
68
- # @raise [RestClient::ResourceNotFound] if the user or key does not exist.
69
- def public_key username, keyname
70
- public_keys_resource(username, keyname).get
71
- end
72
-
73
- # List the public key names for the given user.
74
- #
75
- # If the given user does not exist, an empty Array will be returned. This is to prevent attackers from determining whether
76
- # a user exists.
77
- #
78
- # ## Permissions
79
- # You do not need any special permissions to call this method, since public keys are, well, public.
80
- #
81
- #
82
- # @example List the names of public keys for 'otto'
83
- # api.public_key_names('otto').each{|n| puts n}
84
- # # otto@somehost
85
- # # admin@someotherhost
86
- #
87
- # @example A non existent user has no public keys
88
- # user = api.user('doesnotexist')
89
- # user.exists? # => false
90
- # user.public_key_names # => []
91
- #
92
- # @param [String] username the Conjur username
93
- # @return [Array<String>] the names of the user's public keys
94
- def public_key_names username
95
- public_keys(username).lines.map{|s| s.split(' ')[-1]}
96
- end
97
-
98
- # Add an SSH public key for `username`.
99
- #
100
- # ## Key Format
101
- #
102
- # This method will raise an exception if `key` is not of the format
103
- # `"<algorithm> <data> <name>"` (that is, key.split(\s+\)).length must be 3). The `<name>` field is used by the service
104
- # to identify individual keys for a user.
105
- #
106
- # ## Permissions
107
- #
108
- # You must have permission to `'update'` the pubkeys service resource. When the Conjur appliance
109
- # is configured, it creates the pubkeys service resource with this identifier
110
- # `'<organizational account>:service:pubkeys-1.0/public-keys'`.
111
- #
112
- # Rather than granting permissions to this resource directly to user roles, we recommend that you add them to the
113
- # 'key-managers' group, whose *unqualified identifier* is 'pubkeys-1.0/key-managers', which has permission to add public
114
- # keys.
115
- #
116
- # ## Hiding Existence
117
- #
118
- # Because attackers could use this method to determine the existence of Conjur users, it will not
119
- # raise an error if the user does not exist.
120
- #
121
- # @example add a user's public key
122
- # # Check that the user exists so that we can fail when he doesn't. Otherwise, this method
123
- # # will silently fail.
124
- # raise "No such user!" unless api.user('bob').exists?
125
- #
126
- # # Add a key from a file
127
- # key = File.read('/path/to/public/key.pub')
128
- # api.add_public_key('bob', key)
129
- #
130
- # @param [String] username the name of the Conjur
131
- # @param [String] key an SSH formated public key
132
- # @return void
133
- # @raise RestClient::BadRequest when the key is not in the correct format.
134
- def add_public_key username, key
135
- public_keys_resource(username).post key
136
- end
137
-
138
- # Delete a specific public key for a user.
139
- #
140
- # ## Permissions
141
- # You must have permission to `'update'` the pubkeys service resource. When the Conjur appliance
142
- # is configured, it creates the pubkeys service resource with this identifier
143
- # `'<organizational account>:service:pubkeys-1.0/public-keys'`.
144
- #
145
- # Rather than granting permissions to this resource directly to user roles, we recommend that you add them to the
146
- # 'key-managers' group, whose *unqualified identifier* is 'pubkeys-1.0/key-managers', which has permission to add public
147
- # keys.
148
- #
149
- # ## Hiding Existence
150
- #
151
- # Because attackers could use this method to determine the existence of Conjur users, it will not
152
- # raise an error if the user does not exist.
153
- #
154
- # @example Delete all public keys for 'bob'
155
- #
156
- # api.public_key_names('bob').count # => 6
157
- # api.public_key_names('bob').each do |keyname|
158
- # api.delete_public_key 'bob', keyname
159
- # end
160
- # api.public_key_names('bob').count # => 0
161
- #
162
- #
163
- # @param [String] username the Conjur username/login
164
- # @param [String] keyname the individual key to delete.
165
- # @return [void]
166
- def delete_public_key username, keyname
167
- public_keys_resource(username, keyname).delete
168
- end
169
-
170
- #@!endgroup
171
-
172
- protected
173
- # @api private
174
- # Returns a RestClient::Resource with the pubkeys host and the given path.
175
- def public_keys_resource *path
176
- RestClient::Resource.new(Conjur::API.pubkeys_asset_host, credentials)[public_keys_path *path]
177
- end
178
-
179
- # @api private
180
- # This method simply escapes each segment in `args` and joins them around `/`.
181
- def public_keys_path *args
182
- args.map{|a| fully_escape(a)}.join('/')
24
+ class API
25
+ class << self
26
+ # @!group Public Keys
27
+
28
+ # Fetch *all* public keys for the user. This method returns a newline delimited
29
+ # String for compatibility with the authorized_keys SSH format.
30
+ #
31
+ #
32
+ # If the given user does not exist, an empty String will be returned. This is to prevent attackers from determining whether
33
+ # a user exists.
34
+ #
35
+ # ## Permissions
36
+ # You do not need any special permissions to call this method, since public keys are, well, public.
37
+ #
38
+ #
39
+ # @example
40
+ # puts api.public_keys('jon')
41
+ # # ssh-rsa [big long string] jon@albert
42
+ # # ssh-rsa [big long string] jon@conjurops
43
+ #
44
+ # @param [String] username the *unqualified* Conjur username
45
+ # @return [String] newline delimited public keys
46
+ def public_keys username, account: Conjur.configuration.account
47
+ public_keys_resource(username, account).get
48
+ end
49
+
50
+ #@!endgroup
51
+
52
+ protected
53
+
54
+ # @api private
55
+ # Returns a RestClient::Resource with the pubkeys host and the given path.
56
+ def public_keys_resource username, account
57
+ RestClient::Resource.new(Conjur.configuration.core_url)['public_keys'][fully_escape account]['user'][path_escape username]
58
+ end
183
59
  end
184
60
  end
185
61
  end