chef-zero 4.3.0 → 4.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +201 -201
  3. data/README.md +155 -155
  4. data/Rakefile +31 -31
  5. data/bin/chef-zero +100 -100
  6. data/lib/chef_zero.rb +10 -10
  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 +208 -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 -94
  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 -22
  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 -30
  52. data/lib/chef_zero/endpoints/organization_authenticate_user_endpoint.rb +26 -26
  53. data/lib/chef_zero/endpoints/organization_endpoint.rb +46 -46
  54. data/lib/chef_zero/endpoints/organization_user_base.rb +15 -15
  55. data/lib/chef_zero/endpoints/organization_user_endpoint.rb +26 -26
  56. data/lib/chef_zero/endpoints/organization_users_endpoint.rb +43 -43
  57. data/lib/chef_zero/endpoints/organization_validator_key_endpoint.rb +20 -20
  58. data/lib/chef_zero/endpoints/organizations_endpoint.rb +62 -62
  59. data/lib/chef_zero/endpoints/policies_endpoint.rb +151 -151
  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 -194
  68. data/lib/chef_zero/endpoints/searches_endpoint.rb +18 -18
  69. data/lib/chef_zero/endpoints/server_api_version_endpoint.rb +14 -14
  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 -242
  78. data/lib/chef_zero/rest_error_response.rb +11 -11
  79. data/lib/chef_zero/rest_request.rb +69 -69
  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 -642
  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 -63
  95. data/spec/search_spec.rb +32 -32
  96. data/spec/server_spec.rb +92 -92
  97. data/spec/socketless_server_map_spec.rb +76 -76
  98. data/spec/support/oc_pedant.rb +132 -132
  99. data/spec/support/stickywicket.pem +27 -27
  100. metadata +3 -3
@@ -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,94 +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
-
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
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