chef-zero 4.2.3 → 4.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +201 -201
  3. data/README.md +155 -150
  4. data/Rakefile +31 -31
  5. data/bin/chef-zero +100 -100
  6. data/lib/chef_zero.rb +10 -7
  7. data/lib/chef_zero/chef_data/acl_path.rb +139 -139
  8. data/lib/chef_zero/chef_data/cookbook_data.rb +240 -240
  9. data/lib/chef_zero/chef_data/data_normalizer.rb +207 -207
  10. data/lib/chef_zero/chef_data/default_creator.rb +446 -446
  11. data/lib/chef_zero/data_store/data_already_exists_error.rb +29 -29
  12. data/lib/chef_zero/data_store/data_error.rb +31 -31
  13. data/lib/chef_zero/data_store/data_not_found_error.rb +28 -28
  14. data/lib/chef_zero/data_store/default_facade.rb +149 -149
  15. data/lib/chef_zero/data_store/interface_v1.rb +67 -67
  16. data/lib/chef_zero/data_store/interface_v2.rb +18 -18
  17. data/lib/chef_zero/data_store/memory_store.rb +33 -33
  18. data/lib/chef_zero/data_store/memory_store_v2.rb +155 -155
  19. data/lib/chef_zero/data_store/raw_file_store.rb +147 -147
  20. data/lib/chef_zero/data_store/v1_to_v2_adapter.rb +142 -142
  21. data/lib/chef_zero/data_store/v2_to_v1_adapter.rb +107 -107
  22. data/lib/chef_zero/endpoints/acl_endpoint.rb +38 -38
  23. data/lib/chef_zero/endpoints/acls_endpoint.rb +29 -29
  24. data/lib/chef_zero/endpoints/actor_endpoint.rb +94 -88
  25. data/lib/chef_zero/endpoints/actors_endpoint.rb +64 -64
  26. data/lib/chef_zero/endpoints/authenticate_user_endpoint.rb +31 -31
  27. data/lib/chef_zero/endpoints/container_endpoint.rb +22 -22
  28. data/lib/chef_zero/endpoints/containers_endpoint.rb +13 -13
  29. data/lib/chef_zero/endpoints/cookbook_endpoint.rb +39 -39
  30. data/lib/chef_zero/endpoints/cookbook_version_endpoint.rb +119 -119
  31. data/lib/chef_zero/endpoints/cookbooks_base.rb +65 -65
  32. data/lib/chef_zero/endpoints/cookbooks_endpoint.rb +19 -19
  33. data/lib/chef_zero/endpoints/data_bag_endpoint.rb +45 -45
  34. data/lib/chef_zero/endpoints/data_bag_item_endpoint.rb +25 -25
  35. data/lib/chef_zero/endpoints/data_bags_endpoint.rb +23 -23
  36. data/lib/chef_zero/endpoints/environment_cookbook_endpoint.rb +24 -24
  37. data/lib/chef_zero/endpoints/environment_cookbook_versions_endpoint.rb +123 -123
  38. data/lib/chef_zero/endpoints/environment_cookbooks_endpoint.rb +22 -22
  39. data/lib/chef_zero/endpoints/environment_endpoint.rb +33 -33
  40. data/lib/chef_zero/endpoints/environment_nodes_endpoint.rb +23 -23
  41. data/lib/chef_zero/endpoints/environment_recipes_endpoint.rb +22 -22
  42. data/lib/chef_zero/endpoints/environment_role_endpoint.rb +36 -36
  43. data/lib/chef_zero/endpoints/file_store_file_endpoint.rb +22 -22
  44. data/lib/chef_zero/endpoints/group_endpoint.rb +20 -20
  45. data/lib/chef_zero/endpoints/groups_endpoint.rb +13 -13
  46. data/lib/chef_zero/endpoints/license_endpoint.rb +25 -25
  47. data/lib/chef_zero/endpoints/node_endpoint.rb +17 -17
  48. data/lib/chef_zero/endpoints/node_identifiers_endpoint.rb +22 -0
  49. data/lib/chef_zero/endpoints/not_found_endpoint.rb +11 -11
  50. data/lib/chef_zero/endpoints/organization_association_request_endpoint.rb +22 -22
  51. data/lib/chef_zero/endpoints/organization_association_requests_endpoint.rb +30 -29
  52. data/lib/chef_zero/endpoints/organization_authenticate_user_endpoint.rb +26 -26
  53. data/lib/chef_zero/endpoints/organization_endpoint.rb +46 -41
  54. data/lib/chef_zero/endpoints/organization_user_base.rb +15 -0
  55. data/lib/chef_zero/endpoints/organization_user_endpoint.rb +26 -48
  56. data/lib/chef_zero/endpoints/organization_users_endpoint.rb +43 -14
  57. data/lib/chef_zero/endpoints/organization_validator_key_endpoint.rb +20 -20
  58. data/lib/chef_zero/endpoints/organizations_endpoint.rb +62 -55
  59. data/lib/chef_zero/endpoints/policies_endpoint.rb +151 -154
  60. data/lib/chef_zero/endpoints/principal_endpoint.rb +42 -42
  61. data/lib/chef_zero/endpoints/rest_list_endpoint.rb +42 -42
  62. data/lib/chef_zero/endpoints/rest_object_endpoint.rb +63 -63
  63. data/lib/chef_zero/endpoints/role_endpoint.rb +16 -16
  64. data/lib/chef_zero/endpoints/role_environments_endpoint.rb +14 -14
  65. data/lib/chef_zero/endpoints/sandbox_endpoint.rb +27 -27
  66. data/lib/chef_zero/endpoints/sandboxes_endpoint.rb +50 -50
  67. data/lib/chef_zero/endpoints/search_endpoint.rb +194 -192
  68. data/lib/chef_zero/endpoints/searches_endpoint.rb +18 -18
  69. data/lib/chef_zero/endpoints/server_api_version_endpoint.rb +14 -0
  70. data/lib/chef_zero/endpoints/system_recovery_endpoint.rb +30 -30
  71. data/lib/chef_zero/endpoints/user_association_request_endpoint.rb +40 -40
  72. data/lib/chef_zero/endpoints/user_association_requests_count_endpoint.rb +19 -19
  73. data/lib/chef_zero/endpoints/user_association_requests_endpoint.rb +19 -19
  74. data/lib/chef_zero/endpoints/user_organizations_endpoint.rb +22 -22
  75. data/lib/chef_zero/endpoints/version_endpoint.rb +12 -12
  76. data/lib/chef_zero/log.rb +7 -7
  77. data/lib/chef_zero/rest_base.rb +242 -214
  78. data/lib/chef_zero/rest_error_response.rb +11 -11
  79. data/lib/chef_zero/rest_request.rb +69 -65
  80. data/lib/chef_zero/rest_router.rb +45 -45
  81. data/lib/chef_zero/rspec.rb +308 -308
  82. data/lib/chef_zero/server.rb +642 -637
  83. data/lib/chef_zero/socketless_server_map.rb +92 -92
  84. data/lib/chef_zero/solr/query/binary_operator.rb +52 -52
  85. data/lib/chef_zero/solr/query/phrase.rb +23 -23
  86. data/lib/chef_zero/solr/query/range_query.rb +46 -46
  87. data/lib/chef_zero/solr/query/regexpable_query.rb +29 -29
  88. data/lib/chef_zero/solr/query/subquery.rb +37 -37
  89. data/lib/chef_zero/solr/query/term.rb +45 -45
  90. data/lib/chef_zero/solr/query/unary_operator.rb +43 -43
  91. data/lib/chef_zero/solr/solr_doc.rb +53 -53
  92. data/lib/chef_zero/solr/solr_parser.rb +203 -203
  93. data/lib/chef_zero/version.rb +3 -3
  94. data/spec/run_oc_pedant.rb +63 -56
  95. data/spec/search_spec.rb +32 -32
  96. data/spec/server_spec.rb +92 -91
  97. data/spec/socketless_server_map_spec.rb +76 -76
  98. data/spec/support/oc_pedant.rb +132 -134
  99. data/spec/support/stickywicket.pem +27 -27
  100. metadata +10 -15
  101. data/spec/run_pedant.rb +0 -103
  102. data/spec/support/pedant.rb +0 -129
@@ -1,107 +1,107 @@
1
- #
2
- # Author:: John Keiser (<jkeiser@opscode.com>)
3
- # Copyright:: Copyright (c) 2014 Opscode, Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- require 'chef_zero/data_store/interface_v1'
20
-
21
- module ChefZero
22
- module DataStore
23
- class V2ToV1Adapter < ChefZero::DataStore::InterfaceV1
24
- def initialize
25
- @single_org = 'chef'
26
- end
27
-
28
- attr_reader :real_store
29
- attr_reader :single_org
30
-
31
- def clear
32
- real_store.clear
33
- real_store.create_dir([ 'organizations' ], single_org, :recursive)
34
- end
35
-
36
- def create_dir(path, name, *options)
37
- fix_exceptions do
38
- real_store.create_dir(fix_path(path), name, *options)
39
- end
40
- end
41
-
42
- def create(path, name, data, *options)
43
- fix_exceptions do
44
- real_store.create(fix_path(path), name, data, *options)
45
- end
46
- end
47
-
48
- def get(path, request=nil)
49
- fix_exceptions do
50
- real_store.get(fix_path(path), request)
51
- end
52
- end
53
-
54
- def set(path, data, *options)
55
- fix_exceptions do
56
- real_store.set(fix_path(path), data, *options)
57
- end
58
- end
59
-
60
- def delete(path)
61
- fix_exceptions do
62
- real_store.delete(fix_path(path))
63
- end
64
- end
65
-
66
- def delete_dir(path, *options)
67
- fix_exceptions do
68
- real_store.delete_dir(fix_path(path), *options)
69
- end
70
- end
71
-
72
- def list(path)
73
- fix_exceptions do
74
- real_store.list(fix_path(path))
75
- end
76
- end
77
-
78
- def exists?(path)
79
- fix_exceptions do
80
- real_store.exists?(fix_path(path))
81
- end
82
- end
83
-
84
- def exists_dir?(path)
85
- fix_exceptions do
86
- real_store.exists_dir?(fix_path(path))
87
- end
88
- end
89
-
90
- protected
91
-
92
- def fix_exceptions
93
- begin
94
- yield
95
- rescue DataAlreadyExistsError => e
96
- raise DataAlreadyExistsError.new(e.path[2..-1], e)
97
- rescue DataNotFoundError => e
98
- raise DataNotFoundError.new(e.path[2..-1], e)
99
- end
100
- end
101
-
102
- def fix_path(path)
103
- [ 'organizations', single_org ] + path
104
- end
105
- end
106
- end
107
- end
1
+ #
2
+ # Author:: John Keiser (<jkeiser@opscode.com>)
3
+ # Copyright:: Copyright (c) 2014 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef_zero/data_store/interface_v1'
20
+
21
+ module ChefZero
22
+ module DataStore
23
+ class V2ToV1Adapter < ChefZero::DataStore::InterfaceV1
24
+ def initialize
25
+ @single_org = 'chef'
26
+ end
27
+
28
+ attr_reader :real_store
29
+ attr_reader :single_org
30
+
31
+ def clear
32
+ real_store.clear
33
+ real_store.create_dir([ 'organizations' ], single_org, :recursive)
34
+ end
35
+
36
+ def create_dir(path, name, *options)
37
+ fix_exceptions do
38
+ real_store.create_dir(fix_path(path), name, *options)
39
+ end
40
+ end
41
+
42
+ def create(path, name, data, *options)
43
+ fix_exceptions do
44
+ real_store.create(fix_path(path), name, data, *options)
45
+ end
46
+ end
47
+
48
+ def get(path, request=nil)
49
+ fix_exceptions do
50
+ real_store.get(fix_path(path), request)
51
+ end
52
+ end
53
+
54
+ def set(path, data, *options)
55
+ fix_exceptions do
56
+ real_store.set(fix_path(path), data, *options)
57
+ end
58
+ end
59
+
60
+ def delete(path)
61
+ fix_exceptions do
62
+ real_store.delete(fix_path(path))
63
+ end
64
+ end
65
+
66
+ def delete_dir(path, *options)
67
+ fix_exceptions do
68
+ real_store.delete_dir(fix_path(path), *options)
69
+ end
70
+ end
71
+
72
+ def list(path)
73
+ fix_exceptions do
74
+ real_store.list(fix_path(path))
75
+ end
76
+ end
77
+
78
+ def exists?(path)
79
+ fix_exceptions do
80
+ real_store.exists?(fix_path(path))
81
+ end
82
+ end
83
+
84
+ def exists_dir?(path)
85
+ fix_exceptions do
86
+ real_store.exists_dir?(fix_path(path))
87
+ end
88
+ end
89
+
90
+ protected
91
+
92
+ def fix_exceptions
93
+ begin
94
+ yield
95
+ rescue DataAlreadyExistsError => e
96
+ raise DataAlreadyExistsError.new(e.path[2..-1], e)
97
+ rescue DataNotFoundError => e
98
+ raise DataNotFoundError.new(e.path[2..-1], e)
99
+ end
100
+ end
101
+
102
+ def fix_path(path)
103
+ [ 'organizations', single_org ] + path
104
+ end
105
+ end
106
+ end
107
+ end
@@ -1,38 +1,38 @@
1
- require 'ffi_yajl'
2
- require 'chef_zero/rest_base'
3
- require 'chef_zero/chef_data/acl_path'
4
-
5
- module ChefZero
6
- module Endpoints
7
- # /organizations/ORG/<thing>/NAME/_acl/PERM
8
- # Where thing is:
9
- # clients, data, containers, cookbooks, environments
10
- # groups, roles, nodes, users
11
- # or
12
- # /organizations/ORG/organization/_acl/PERM
13
- # or
14
- # /users/NAME/_acl/PERM
15
- #
16
- # Where PERM is create,read,update,delete,grant
17
- class AclEndpoint < RestBase
18
- def validate_request(request)
19
- path = request.rest_path[0..-3] # Strip off _acl/PERM
20
- path = path[0..1] if path.size == 3 && path[0] == 'organizations' && %w(organization organizations).include?(path[2])
21
- acl_path = ChefData::AclPath.get_acl_data_path(path)
22
- perm = request.rest_path[-1]
23
- if !acl_path || !%w(read create update delete grant).include?(perm)
24
- raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, request.rest_path)}")
25
- end
26
- [acl_path, perm]
27
- end
28
-
29
- def put(request)
30
- path, perm = validate_request(request)
31
- acls = FFI_Yajl::Parser.parse(get_data(request, path), :create_additions => false)
32
- acls[perm] = FFI_Yajl::Parser.parse(request.body, :create_additions => false)[perm]
33
- set_data(request, path, FFI_Yajl::Encoder.encode(acls, :pretty => true))
34
- json_response(200, {'uri' => "#{build_uri(request.base_uri, request.rest_path)}"})
35
- end
36
- end
37
- end
38
- end
1
+ require 'ffi_yajl'
2
+ require 'chef_zero/rest_base'
3
+ require 'chef_zero/chef_data/acl_path'
4
+
5
+ module ChefZero
6
+ module Endpoints
7
+ # /organizations/ORG/<thing>/NAME/_acl/PERM
8
+ # Where thing is:
9
+ # clients, data, containers, cookbooks, environments
10
+ # groups, roles, nodes, users
11
+ # or
12
+ # /organizations/ORG/organization/_acl/PERM
13
+ # or
14
+ # /users/NAME/_acl/PERM
15
+ #
16
+ # Where PERM is create,read,update,delete,grant
17
+ class AclEndpoint < RestBase
18
+ def validate_request(request)
19
+ path = request.rest_path[0..-3] # Strip off _acl/PERM
20
+ path = path[0..1] if path.size == 3 && path[0] == 'organizations' && %w(organization organizations).include?(path[2])
21
+ acl_path = ChefData::AclPath.get_acl_data_path(path)
22
+ perm = request.rest_path[-1]
23
+ if !acl_path || !%w(read create update delete grant).include?(perm)
24
+ raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, request.rest_path)}")
25
+ end
26
+ [acl_path, perm]
27
+ end
28
+
29
+ def put(request)
30
+ path, perm = validate_request(request)
31
+ acls = FFI_Yajl::Parser.parse(get_data(request, path), :create_additions => false)
32
+ acls[perm] = FFI_Yajl::Parser.parse(request.body, :create_additions => false)[perm]
33
+ set_data(request, path, FFI_Yajl::Encoder.encode(acls, :pretty => true))
34
+ json_response(200, {'uri' => "#{build_uri(request.base_uri, request.rest_path)}"})
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,29 +1,29 @@
1
- require 'ffi_yajl'
2
- require 'chef_zero/rest_base'
3
- require 'chef_zero/chef_data/data_normalizer'
4
- require 'chef_zero/chef_data/acl_path'
5
-
6
- module ChefZero
7
- module Endpoints
8
- # /organizations/ORG/THING/NAME/_acl
9
- # Where THING is:
10
- # - clients, data, containers, cookbooks, environments
11
- # groups, roles, nodes, users
12
- # or
13
- # /organizations/ORG/organization/_acl
14
- # /users/NAME/_acl
15
- class AclsEndpoint < RestBase
16
- def get(request)
17
- path = request.rest_path[0..-2] # Strip off _acl
18
- path = path[0..1] if path.size == 3 && path[0] == 'organizations' && %w(organization organizations).include?(path[2])
19
- acl_path = ChefData::AclPath.get_acl_data_path(path)
20
- if !acl_path
21
- raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, request.rest_path)}")
22
- end
23
- acls = FFI_Yajl::Parser.parse(get_data(request, acl_path), :create_additions => false)
24
- acls = ChefData::DataNormalizer.normalize_acls(acls)
25
- json_response(200, acls)
26
- end
27
- end
28
- end
29
- end
1
+ require 'ffi_yajl'
2
+ require 'chef_zero/rest_base'
3
+ require 'chef_zero/chef_data/data_normalizer'
4
+ require 'chef_zero/chef_data/acl_path'
5
+
6
+ module ChefZero
7
+ module Endpoints
8
+ # /organizations/ORG/THING/NAME/_acl
9
+ # Where THING is:
10
+ # - clients, data, containers, cookbooks, environments
11
+ # groups, roles, nodes, users
12
+ # or
13
+ # /organizations/ORG/organization/_acl
14
+ # /users/NAME/_acl
15
+ class AclsEndpoint < RestBase
16
+ def get(request)
17
+ path = request.rest_path[0..-2] # Strip off _acl
18
+ path = path[0..1] if path.size == 3 && path[0] == 'organizations' && %w(organization organizations).include?(path[2])
19
+ acl_path = ChefData::AclPath.get_acl_data_path(path)
20
+ if !acl_path
21
+ raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, request.rest_path)}")
22
+ end
23
+ acls = FFI_Yajl::Parser.parse(get_data(request, acl_path), :create_additions => false)
24
+ acls = ChefData::DataNormalizer.normalize_acls(acls)
25
+ json_response(200, acls)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,88 +1,94 @@
1
- require 'ffi_yajl'
2
- require 'chef_zero/endpoints/rest_object_endpoint'
3
- require 'chef_zero/chef_data/data_normalizer'
4
-
5
- module ChefZero
6
- module Endpoints
7
- # /organizations/ORG/clients/NAME
8
- # /organizations/ORG/users/NAME
9
- # /users/NAME
10
- class ActorEndpoint < RestObjectEndpoint
11
- def delete(request)
12
- result = super
13
- if request.rest_path[0] == 'users'
14
- list_data(request, [ 'organizations' ]).each do |org|
15
- begin
16
- delete_data(request, [ 'organizations', org, 'users', request.rest_path[1] ], :data_store_exceptions)
17
- rescue DataStore::DataNotFoundError
18
- end
19
- end
20
- end
21
- result
22
- end
23
-
24
- def put(request)
25
- # Find out if we're updating the public key.
26
- request_body = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
27
- if request_body['public_key'].nil?
28
- # If public_key is null, then don't overwrite it. Weird patchiness.
29
- body_modified = true
30
- request_body.delete('public_key')
31
- else
32
- updating_public_key = true
33
- end
34
-
35
- # Generate private_key if requested.
36
- if request_body.has_key?('private_key')
37
- body_modified = true
38
- if request_body['private_key']
39
- private_key, public_key = server.gen_key_pair
40
- updating_public_key = true
41
- request_body['public_key'] = public_key
42
- end
43
- request_body.delete('private_key')
44
- end
45
-
46
- # Save request
47
- request.body = FFI_Yajl::Encoder.encode(request_body, :pretty => true) if body_modified
48
-
49
- # PUT /clients is patchy
50
- request.body = patch_request_body(request)
51
-
52
- result = super(request)
53
-
54
- # Inject private_key into response, delete public_key/password if applicable
55
- if result[0] == 200 || result[0] == 201
56
- if request.rest_path[0] == 'users'
57
- key = nil
58
- identity_keys.each do |identity_key|
59
- key ||= request_body[identity_key]
60
- end
61
- key ||= request.rest_path[-1]
62
- response = {
63
- 'uri' => build_uri(request.base_uri, [ 'users', key ])
64
- }
65
- else
66
- response = FFI_Yajl::Parser.parse(result[2], :create_additions => false)
67
- end
68
- response['private_key'] = private_key if private_key
69
- response.delete('public_key') if !updating_public_key && request.rest_path[2] == 'users'
70
- response.delete('password')
71
- json_response(result[0], response)
72
- else
73
- result
74
- end
75
- end
76
-
77
- def populate_defaults(request, response_json)
78
- response = FFI_Yajl::Parser.parse(response_json, :create_additions => false)
79
- if request.rest_path[2] == 'clients'
80
- response = ChefData::DataNormalizer.normalize_client(response, request.rest_path[3])
81
- else
82
- response = ChefData::DataNormalizer.normalize_user(response, request.rest_path[3], identity_keys, server.options[:osc_compat], request.method)
83
- end
84
- FFI_Yajl::Encoder.encode(response, :pretty => true)
85
- end
86
- end
87
- end
88
- end
1
+ require 'ffi_yajl'
2
+ require 'chef_zero/endpoints/rest_object_endpoint'
3
+ require 'chef_zero/chef_data/data_normalizer'
4
+
5
+ module ChefZero
6
+ module Endpoints
7
+ # /organizations/ORG/clients/NAME
8
+ # /organizations/ORG/users/NAME
9
+ # /users/NAME
10
+ class ActorEndpoint < RestObjectEndpoint
11
+ def delete(request)
12
+ result = super
13
+ if request.rest_path[0] == 'users'
14
+ list_data(request, [ 'organizations' ]).each do |org|
15
+ begin
16
+ delete_data(request, [ 'organizations', org, 'users', request.rest_path[1] ], :data_store_exceptions)
17
+ rescue DataStore::DataNotFoundError
18
+ end
19
+ end
20
+ end
21
+ result
22
+ end
23
+
24
+ def put(request)
25
+ # Find out if we're updating the public key.
26
+ request_body = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
27
+ if request_body['public_key'].nil?
28
+ # If public_key is null, then don't overwrite it. Weird patchiness.
29
+ body_modified = true
30
+ request_body.delete('public_key')
31
+ else
32
+ updating_public_key = true
33
+ end
34
+
35
+ # Generate private_key if requested.
36
+ if request_body.has_key?('private_key')
37
+ body_modified = true
38
+ if request_body['private_key']
39
+ private_key, public_key = server.gen_key_pair
40
+ updating_public_key = true
41
+ request_body['public_key'] = public_key
42
+ end
43
+ request_body.delete('private_key')
44
+ end
45
+
46
+ # Save request
47
+ request.body = FFI_Yajl::Encoder.encode(request_body, :pretty => true) if body_modified
48
+
49
+ # PUT /clients is patchy
50
+ request.body = patch_request_body(request)
51
+
52
+ result = super(request)
53
+
54
+ # Inject private_key into response, delete public_key/password if applicable
55
+ if result[0] == 200 || result[0] == 201
56
+ if request.rest_path[0] == 'users'
57
+ key = nil
58
+ identity_keys.each do |identity_key|
59
+ key ||= request_body[identity_key]
60
+ end
61
+ key ||= request.rest_path[-1]
62
+ response = {
63
+ 'uri' => build_uri(request.base_uri, [ 'users', key ])
64
+ }
65
+ else
66
+ response = FFI_Yajl::Parser.parse(result[2], :create_additions => false)
67
+ end
68
+
69
+ if request.rest_path[2] == 'clients'
70
+ response['private_key'] = private_key ? private_key : false
71
+ else
72
+ response['private_key'] = private_key if private_key
73
+ end
74
+
75
+ response.delete('public_key') if !updating_public_key && request.rest_path[2] == 'users'
76
+ response.delete('password')
77
+ json_response(result[0], response)
78
+ else
79
+ result
80
+ end
81
+ end
82
+
83
+ def populate_defaults(request, response_json)
84
+ response = FFI_Yajl::Parser.parse(response_json, :create_additions => false)
85
+ if request.rest_path[2] == 'clients'
86
+ response = ChefData::DataNormalizer.normalize_client(response,request.rest_path[3], request.rest_path[1])
87
+ else
88
+ response = ChefData::DataNormalizer.normalize_user(response, request.rest_path[3], identity_keys, server.options[:osc_compat], request.method)
89
+ end
90
+ FFI_Yajl::Encoder.encode(response, :pretty => true)
91
+ end
92
+ end
93
+ end
94
+ end