chef-zero 2.2.1 → 3.0.0.rc.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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/Rakefile +5 -1
  4. data/bin/chef-zero +17 -0
  5. data/lib/chef_zero/chef_data/acl_path.rb +139 -0
  6. data/lib/chef_zero/chef_data/cookbook_data.rb +240 -0
  7. data/lib/chef_zero/chef_data/data_normalizer.rb +207 -0
  8. data/lib/chef_zero/chef_data/default_creator.rb +446 -0
  9. data/lib/chef_zero/data_store/default_facade.rb +149 -0
  10. data/lib/chef_zero/data_store/interface_v1.rb +18 -0
  11. data/lib/chef_zero/data_store/memory_store.rb +2 -1
  12. data/lib/chef_zero/data_store/memory_store_v2.rb +3 -36
  13. data/lib/chef_zero/data_store/raw_file_store.rb +147 -0
  14. data/lib/chef_zero/data_store/v1_to_v2_adapter.rb +39 -103
  15. data/lib/chef_zero/data_store/v2_to_v1_adapter.rb +1 -1
  16. data/lib/chef_zero/endpoints/acl_endpoint.rb +38 -0
  17. data/lib/chef_zero/endpoints/acls_endpoint.rb +29 -0
  18. data/lib/chef_zero/endpoints/actor_endpoint.rb +36 -10
  19. data/lib/chef_zero/endpoints/actors_endpoint.rb +38 -6
  20. data/lib/chef_zero/endpoints/authenticate_user_endpoint.rb +15 -9
  21. data/lib/chef_zero/endpoints/container_endpoint.rb +22 -0
  22. data/lib/chef_zero/endpoints/containers_endpoint.rb +13 -0
  23. data/lib/chef_zero/endpoints/cookbook_endpoint.rb +1 -1
  24. data/lib/chef_zero/endpoints/cookbook_version_endpoint.rb +15 -14
  25. data/lib/chef_zero/endpoints/cookbooks_base.rb +2 -2
  26. data/lib/chef_zero/endpoints/data_bag_endpoint.rb +4 -4
  27. data/lib/chef_zero/endpoints/data_bag_item_endpoint.rb +5 -5
  28. data/lib/chef_zero/endpoints/data_bags_endpoint.rb +5 -4
  29. data/lib/chef_zero/endpoints/environment_cookbook_endpoint.rb +2 -2
  30. data/lib/chef_zero/endpoints/environment_cookbook_versions_endpoint.rb +6 -6
  31. data/lib/chef_zero/endpoints/environment_cookbooks_endpoint.rb +2 -2
  32. data/lib/chef_zero/endpoints/environment_endpoint.rb +5 -5
  33. data/lib/chef_zero/endpoints/environment_nodes_endpoint.rb +2 -2
  34. data/lib/chef_zero/endpoints/environment_recipes_endpoint.rb +3 -3
  35. data/lib/chef_zero/endpoints/environment_role_endpoint.rb +2 -2
  36. data/lib/chef_zero/endpoints/file_store_file_endpoint.rb +1 -1
  37. data/lib/chef_zero/endpoints/group_endpoint.rb +20 -0
  38. data/lib/chef_zero/endpoints/groups_endpoint.rb +13 -0
  39. data/lib/chef_zero/endpoints/license_endpoint.rb +25 -0
  40. data/lib/chef_zero/endpoints/node_endpoint.rb +5 -5
  41. data/lib/chef_zero/endpoints/not_found_endpoint.rb +2 -2
  42. data/lib/chef_zero/endpoints/organization_association_request_endpoint.rb +22 -0
  43. data/lib/chef_zero/endpoints/organization_association_requests_endpoint.rb +29 -0
  44. data/lib/chef_zero/endpoints/organization_authenticate_user_endpoint.rb +26 -0
  45. data/lib/chef_zero/endpoints/organization_endpoint.rb +41 -0
  46. data/lib/chef_zero/endpoints/organization_user_endpoint.rb +48 -0
  47. data/lib/chef_zero/endpoints/organization_users_endpoint.rb +14 -0
  48. data/lib/chef_zero/endpoints/organization_validator_key_endpoint.rb +20 -0
  49. data/lib/chef_zero/endpoints/organizations_endpoint.rb +55 -0
  50. data/lib/chef_zero/endpoints/principal_endpoint.rb +15 -3
  51. data/lib/chef_zero/endpoints/rest_list_endpoint.rb +8 -6
  52. data/lib/chef_zero/endpoints/rest_object_endpoint.rb +12 -10
  53. data/lib/chef_zero/endpoints/role_endpoint.rb +5 -5
  54. data/lib/chef_zero/endpoints/role_environments_endpoint.rb +2 -2
  55. data/lib/chef_zero/endpoints/sandbox_endpoint.rb +2 -2
  56. data/lib/chef_zero/endpoints/sandboxes_endpoint.rb +4 -4
  57. data/lib/chef_zero/endpoints/search_endpoint.rb +10 -10
  58. data/lib/chef_zero/endpoints/system_recovery_endpoint.rb +30 -0
  59. data/lib/chef_zero/endpoints/user_association_request_endpoint.rb +40 -0
  60. data/lib/chef_zero/endpoints/user_association_requests_count_endpoint.rb +19 -0
  61. data/lib/chef_zero/endpoints/user_association_requests_endpoint.rb +19 -0
  62. data/lib/chef_zero/endpoints/user_organizations_endpoint.rb +22 -0
  63. data/lib/chef_zero/rest_base.rb +79 -13
  64. data/lib/chef_zero/rest_error_response.rb +1 -1
  65. data/lib/chef_zero/rest_request.rb +4 -0
  66. data/lib/chef_zero/rest_router.rb +1 -0
  67. data/lib/chef_zero/rspec.rb +55 -8
  68. data/lib/chef_zero/server.rb +87 -21
  69. data/lib/chef_zero/version.rb +1 -1
  70. data/spec/run_oc_pedant.rb +53 -0
  71. data/spec/{run.rb → run_pedant.rb} +13 -4
  72. data/spec/server_spec.rb +54 -0
  73. data/spec/support/oc_pedant.rb +134 -0
  74. data/spec/support/pedant.rb +1 -1
  75. metadata +54 -13
  76. data/lib/chef_zero/cookbook_data.rb +0 -236
  77. data/lib/chef_zero/data_normalizer.rb +0 -146
@@ -0,0 +1,14 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /organizations/ORG/users
7
+ class OrganizationUsersEndpoint < RestBase
8
+ def get(request)
9
+ result = list_data(request).map { |username| { "user" => { "username" => username } } }
10
+ json_response(200, result)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+ require 'uuidtools'
4
+
5
+ module ChefZero
6
+ module Endpoints
7
+ # /organizations/NAME/_validator_key
8
+ class OrganizationValidatorKeyEndpoint < RestBase
9
+ def post(request)
10
+ org_name = request.rest_path[-2]
11
+ validator_path = [ 'organizations', org_name, 'clients', "#{org_name}-validator"]
12
+ validator = JSON.parse(get_data(request, validator_path), :create_additions => false)
13
+ private_key, public_key = server.gen_key_pair
14
+ validator['public_key'] = public_key
15
+ set_data(request, validator_path, JSON.pretty_generate(validator))
16
+ json_response(200, { 'private_key' => private_key })
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,55 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+ require 'uuidtools'
4
+
5
+ module ChefZero
6
+ module Endpoints
7
+ # /organizations
8
+ class OrganizationsEndpoint < RestBase
9
+ def get(request)
10
+ result = {}
11
+ data_store.list(request.rest_path).each do |name|
12
+ result[name] = build_uri(request.base_uri, request.rest_path + [name])
13
+ end
14
+ json_response(200, result)
15
+ end
16
+
17
+ def post(request)
18
+ contents = request.body
19
+ name = JSON.parse(contents, :create_additions => false)['name']
20
+ if name.nil?
21
+ error(400, "Must specify 'name' in JSON")
22
+ elsif exists_data_dir?(request, request.rest_path + [ name ])
23
+ error(409, "Organization already exists")
24
+ else
25
+ create_data_dir(request, request.rest_path, name, :requestor => request.requestor)
26
+
27
+ org = {
28
+ "guid" => UUIDTools::UUID.random_create.to_s.gsub('-', ''),
29
+ "assigned_at" => Time.now.to_s
30
+ }
31
+ org_path = request.rest_path + [ name ]
32
+ set_data(request, org_path + [ 'org' ], JSON.pretty_generate(org))
33
+
34
+ if server.generate_real_keys?
35
+ # Create the validator client
36
+ validator_name = "#{name}-validator"
37
+ validator_path = org_path + [ 'clients', validator_name ]
38
+ private_key, public_key = server.gen_key_pair
39
+ validator = JSON.pretty_generate({
40
+ 'validator' => true,
41
+ 'public_key' => public_key
42
+ })
43
+ set_data(request, validator_path, validator)
44
+ end
45
+
46
+ json_response(201, {
47
+ "uri" => "#{build_uri(request.base_uri, org_path)}",
48
+ "clientname" => validator_name,
49
+ "private_key" => private_key
50
+ })
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero'
3
3
  require 'chef_zero/rest_base'
4
4
 
@@ -11,15 +11,27 @@ module ChefZero
11
11
  json = get_data(request, request.rest_path[0..1] + [ 'users', name ], :nil)
12
12
  if json
13
13
  type = 'user'
14
+ org_member = true
14
15
  else
15
16
  json = get_data(request, request.rest_path[0..1] + [ 'clients', name ], :nil)
16
- type = 'client'
17
+ if json
18
+ type = 'client'
19
+ org_member = true
20
+ else
21
+ json = get_data(request, [ 'users', name ], :nil)
22
+ if json
23
+ type = 'user'
24
+ org_member = false
25
+ end
26
+ end
17
27
  end
18
28
  if json
19
29
  json_response(200, {
20
30
  'name' => name,
21
31
  'type' => type,
22
- 'public_key' => FFI_Yajl::Parser.parse(json)['public_key'] || PUBLIC_KEY
32
+ 'public_key' => JSON.parse(json)['public_key'] || PUBLIC_KEY,
33
+ 'authz_id' => '0'*32,
34
+ 'org_member' => org_member
23
35
  })
24
36
  else
25
37
  error(404, 'Principal not found')
@@ -1,16 +1,17 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/rest_base'
3
3
 
4
4
  module ChefZero
5
5
  module Endpoints
6
6
  # Typical REST list endpoint (/roles or /data/BAG)
7
7
  class RestListEndpoint < RestBase
8
- def initialize(server, identity_key = 'name')
8
+ def initialize(server, identity_keys = [ 'name' ])
9
9
  super(server)
10
- @identity_key = identity_key
10
+ identity_keys = [ identity_keys ] if identity_keys.is_a?(String)
11
+ @identity_keys = identity_keys
11
12
  end
12
13
 
13
- attr_reader :identity_key
14
+ attr_reader :identity_keys
14
15
 
15
16
  def get(request)
16
17
  # Get the result
@@ -25,7 +26,7 @@ module ChefZero
25
26
  contents = request.body
26
27
  key = get_key(contents)
27
28
  if key.nil?
28
- error(400, "Must specify '#{identity_key}' in JSON")
29
+ error(400, "Must specify #{identity_keys.map { |k| k.inspect }.join(' or ')} in JSON")
29
30
  else
30
31
  create_data(request, request.rest_path, key, contents)
31
32
  json_response(201, {'uri' => "#{build_uri(request.base_uri, request.rest_path + [key])}"})
@@ -33,7 +34,8 @@ module ChefZero
33
34
  end
34
35
 
35
36
  def get_key(contents)
36
- FFI_Yajl::Parser.parse(contents, :create_additions => false)[identity_key]
37
+ json = JSON.parse(contents, :create_additions => false)
38
+ identity_keys.map { |k| json[k] }.select { |v| v }.first
37
39
  end
38
40
  end
39
41
  end
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/rest_base'
3
3
  require 'chef_zero/rest_error_response'
4
4
 
@@ -6,12 +6,13 @@ module ChefZero
6
6
  module Endpoints
7
7
  # Typical REST leaf endpoint (/roles/NAME or /data/BAG/NAME)
8
8
  class RestObjectEndpoint < RestBase
9
- def initialize(server, identity_key = 'name')
9
+ def initialize(server, identity_keys = [ 'name' ])
10
10
  super(server)
11
- @identity_key = identity_key
11
+ identity_keys = [ identity_keys ] if identity_keys.is_a?(String)
12
+ @identity_keys = identity_keys
12
13
  end
13
14
 
14
- attr_reader :identity_key
15
+ attr_reader :identity_keys
15
16
 
16
17
  def get(request)
17
18
  already_json_response(200, populate_defaults(request, get_data(request)))
@@ -20,13 +21,14 @@ module ChefZero
20
21
  def put(request)
21
22
  # We grab the old body to trigger a 404 if it doesn't exist
22
23
  old_body = get_data(request)
23
- request_json = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
24
- key = request_json[identity_key] || request.rest_path[-1]
24
+ request_json = JSON.parse(request.body, :create_additions => false)
25
+ key = identity_keys.map { |k| request_json[k] }.select { |v| v }.first
26
+ key ||= request.rest_path[-1]
25
27
  # If it's a rename, check for conflict and delete the old value
26
28
  rename = key != request.rest_path[-1]
27
29
  if rename
28
30
  begin
29
- data_store.create(request.rest_path[0..1] + request.rest_path[2..-2], key, request.body)
31
+ create_data(request, request.rest_path[0..-2], key, request.body, :data_store_exceptions)
30
32
  rescue DataStore::DataAlreadyExistsError
31
33
  return error(409, "Cannot rename '#{request.rest_path[-1]}' to '#{key}': '#{key}' already exists")
32
34
  end
@@ -47,11 +49,11 @@ module ChefZero
47
49
  def patch_request_body(request)
48
50
  existing_value = get_data(request, nil, :nil)
49
51
  if existing_value
50
- request_json = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
51
- existing_json = FFI_Yajl::Parser.parse(existing_value, :create_additions => false)
52
+ request_json = JSON.parse(request.body, :create_additions => false)
53
+ existing_json = JSON.parse(existing_value, :create_additions => false)
52
54
  merged_json = existing_json.merge(request_json)
53
55
  if merged_json.size > request_json.size
54
- return FFI_Yajl::Encoder.encode(merged_json, :pretty => true)
56
+ return JSON.pretty_generate(merged_json)
55
57
  end
56
58
  end
57
59
  request.body
@@ -1,15 +1,15 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/endpoints/rest_object_endpoint'
3
- require 'chef_zero/data_normalizer'
3
+ require 'chef_zero/chef_data/data_normalizer'
4
4
 
5
5
  module ChefZero
6
6
  module Endpoints
7
7
  # /roles/NAME
8
8
  class RoleEndpoint < RestObjectEndpoint
9
9
  def populate_defaults(request, response_json)
10
- role = FFI_Yajl::Parser.parse(response_json, :create_additions => false)
11
- role = DataNormalizer.normalize_role(role, request.rest_path[3])
12
- FFI_Yajl::Encoder.encode(role, :pretty => true)
10
+ role = JSON.parse(response_json, :create_additions => false)
11
+ role = ChefData::DataNormalizer.normalize_role(role, request.rest_path[3])
12
+ JSON.pretty_generate(role)
13
13
  end
14
14
  end
15
15
  end
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/rest_base'
3
3
 
4
4
  module ChefZero
@@ -6,7 +6,7 @@ module ChefZero
6
6
  # /roles/NAME/environments
7
7
  class RoleEnvironmentsEndpoint < RestBase
8
8
  def get(request)
9
- role = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
9
+ role = JSON.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
10
10
  json_response(200, [ '_default' ] + (role['env_run_lists'].keys || []))
11
11
  end
12
12
  end
@@ -1,13 +1,13 @@
1
1
  require 'chef_zero/rest_base'
2
2
  require 'chef_zero/rest_error_response'
3
- require 'ffi_yajl'
3
+ require 'json'
4
4
 
5
5
  module ChefZero
6
6
  module Endpoints
7
7
  # /sandboxes/ID
8
8
  class SandboxEndpoint < RestBase
9
9
  def put(request)
10
- existing_sandbox = FFI_Yajl::Parser.parse(get_data(request), :create_additions => false)
10
+ existing_sandbox = JSON.parse(get_data(request), :create_additions => false)
11
11
  existing_sandbox['checksums'].each do |checksum|
12
12
  if !exists_data?(request, request.rest_path[0..1] + ['file_store', 'checksums', checksum])
13
13
  raise RestErrorResponse.new(503, "Checksum not uploaded: #{checksum}")
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/rest_base'
3
3
 
4
4
  module ChefZero
@@ -13,7 +13,7 @@ module ChefZero
13
13
  def post(request)
14
14
  sandbox_checksums = []
15
15
 
16
- needed_checksums = FFI_Yajl::Parser.parse(request.body, :create_additions => false)['checksums']
16
+ needed_checksums = JSON.parse(request.body, :create_additions => false)['checksums']
17
17
  result_checksums = {}
18
18
  needed_checksums.keys.each do |needed_checksum|
19
19
  if list_data(request, request.rest_path[0..1] + ['file_store', 'checksums']).include?(needed_checksum)
@@ -34,10 +34,10 @@ module ChefZero
34
34
  time_str = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S%z')
35
35
  time_str = "#{time_str[0..21]}:#{time_str[22..23]}"
36
36
 
37
- create_data(request, request.rest_path, id, FFI_Yajl::Encoder.encode({
37
+ create_data(request, request.rest_path, id, JSON.pretty_generate({
38
38
  :create_time => time_str,
39
39
  :checksums => sandbox_checksums
40
- }, :pretty => true))
40
+ }))
41
41
 
42
42
  json_response(201, {
43
43
  :uri => build_uri(request.base_uri, request.rest_path + [id]),
@@ -1,6 +1,6 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/endpoints/rest_object_endpoint'
3
- require 'chef_zero/data_normalizer'
3
+ require 'chef_zero/chef_data/data_normalizer'
4
4
  require 'chef_zero/rest_error_response'
5
5
  require 'chef_zero/solr/solr_parser'
6
6
  require 'chef_zero/solr/solr_doc'
@@ -17,7 +17,7 @@ module ChefZero
17
17
 
18
18
  def post(request)
19
19
  full_results = search(request)
20
- keys = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
20
+ keys = JSON.parse(request.body, :create_additions => false)
21
21
  partial_results = full_results['rows'].map do |name, uri, doc, search_value|
22
22
  data = {}
23
23
  keys.each_pair do |key, path|
@@ -48,15 +48,15 @@ module ChefZero
48
48
  def search_container(request, index)
49
49
  relative_parts, normalize_proc = case index
50
50
  when 'client'
51
- [ ['clients'], Proc.new { |client, name| DataNormalizer.normalize_client(client, name) } ]
51
+ [ ['clients'], Proc.new { |client, name| ChefData::DataNormalizer.normalize_client(client, name) } ]
52
52
  when 'node'
53
- [ ['nodes'], Proc.new { |node, name| DataNormalizer.normalize_node(node, name) } ]
53
+ [ ['nodes'], Proc.new { |node, name| ChefData::DataNormalizer.normalize_node(node, name) } ]
54
54
  when 'environment'
55
- [ ['environments'], Proc.new { |environment, name| DataNormalizer.normalize_environment(environment, name) } ]
55
+ [ ['environments'], Proc.new { |environment, name| ChefData::DataNormalizer.normalize_environment(environment, name) } ]
56
56
  when 'role'
57
- [ ['roles'], Proc.new { |role, name| DataNormalizer.normalize_role(role, name) } ]
57
+ [ ['roles'], Proc.new { |role, name| ChefData::DataNormalizer.normalize_role(role, name) } ]
58
58
  else
59
- [ ['data', index], Proc.new { |data_bag_item, id| DataNormalizer.normalize_data_bag_item(data_bag_item, index, id, 'DELETE') } ]
59
+ [ ['data', index], Proc.new { |data_bag_item, id| ChefData::DataNormalizer.normalize_data_bag_item(data_bag_item, index, id, 'DELETE') } ]
60
60
  end
61
61
  [
62
62
  request.rest_path[0..1] + relative_parts,
@@ -86,7 +86,7 @@ module ChefZero
86
86
  result
87
87
 
88
88
  elsif !%w(client environment role).include?(index)
89
- DataNormalizer.normalize_data_bag_item(value, index, id, 'GET')
89
+ ChefData::DataNormalizer.normalize_data_bag_item(value, index, id, 'GET')
90
90
  else
91
91
  value
92
92
  end
@@ -110,7 +110,7 @@ module ChefZero
110
110
  result = []
111
111
  list_data(request, container).each do |name|
112
112
  value = get_data(request, container + [name])
113
- expanded = expander.call(FFI_Yajl::Parser.parse(value, :create_additions => false), name)
113
+ expanded = expander.call(JSON.parse(value, :create_additions => false), name)
114
114
  result << [ name, build_uri(request.base_uri, container + [name]), expanded, expand_for_indexing(expanded, index, name) ]
115
115
  end
116
116
  result = result.select do |name, uri, value, search_value|
@@ -0,0 +1,30 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /system_recovery
7
+ class SystemRecoveryEndpoint < RestBase
8
+ def post(request)
9
+ request_json = JSON.parse(request.body, :create_additions => false)
10
+ name = request_json['username']
11
+ password = request_json['password']
12
+ user = get_data(request, request.rest_path[0..-2] + ['users', name], :nil)
13
+ if !user
14
+ raise RestErrorResponse.new(403, "Nonexistent user")
15
+ end
16
+
17
+ user = JSON.parse(user, :create_additions => false)
18
+ user = ChefData::DataNormalizer.normalize_user(user, name, [ 'username' ], server.options[:osc_compat])
19
+ if !user['recovery_authentication_enabled']
20
+ raise RestErrorResponse.new(403, "Only users with recovery_authentication_enabled=true may use /system_recovery to log in")
21
+ end
22
+ if user['password'] != password
23
+ raise RestErrorResponse.new(401, "Incorrect password")
24
+ end
25
+
26
+ json_response(200, user)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,40 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /users/USER/association_requests/ID
7
+ class UserAssociationRequestEndpoint < RestBase
8
+ def put(request)
9
+ username = request.rest_path[1]
10
+ id = request.rest_path[3]
11
+ if id !~ /^#{username}-(.+)/
12
+ raise RestErrorResponse.new(400, "Association request #{id} is invalid. Must be #{username}-orgname.")
13
+ end
14
+ orgname = $1
15
+
16
+ json = JSON.parse(request.body, :create_additions => false)
17
+ association_request_path = [ 'organizations', orgname, 'association_requests', username ]
18
+ if json['response'] == 'accept'
19
+ users = get_data(request, [ 'organizations', orgname, 'groups', 'users' ])
20
+ users = JSON.parse(users, :create_additions => false)
21
+
22
+ delete_data(request, association_request_path)
23
+ create_data(request, [ 'organizations', orgname, 'users' ], username, '{}')
24
+
25
+ # Add the user to the users group if it isn't already there
26
+ if !users['users'] || !users['users'].include?(username)
27
+ users['users'] ||= []
28
+ users['users'] |= [ username ]
29
+ set_data(request, [ 'organizations', orgname, 'groups', 'users' ], JSON.pretty_generate(users))
30
+ end
31
+ elsif json['response'] == 'reject'
32
+ delete_data(request, association_request_path)
33
+ else
34
+ raise RestErrorResponse.new(400, "response parameter was missing or set to the wrong value (must be accept or reject)")
35
+ end
36
+ json_response(200, { 'organization' => { 'name' => orgname } })
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,19 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /users/NAME/association_requests/count
7
+ class UserAssociationRequestsCountEndpoint < RestBase
8
+ def get(request)
9
+ get_data(request, request.rest_path[0..-3])
10
+
11
+ username = request.rest_path[1]
12
+ result = list_data(request, [ 'organizations' ]).select do |org|
13
+ exists_data?(request, [ 'organizations', org, 'association_requests', username ])
14
+ end
15
+ json_response(200, { "value" => result.size })
16
+ end
17
+ end
18
+ end
19
+ end