chef-zero 2.2.1 → 3.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/endpoints/rest_list_endpoint'
3
3
 
4
4
  module ChefZero
@@ -7,13 +7,14 @@ module ChefZero
7
7
  class DataBagsEndpoint < RestListEndpoint
8
8
  def post(request)
9
9
  contents = request.body
10
- name = FFI_Yajl::Parser.parse(contents, :create_additions => false)[identity_key]
10
+ json = JSON.parse(contents, :create_additions => false)
11
+ name = identity_keys.map { |k| json[k] }.select { |v| v }.first
11
12
  if name.nil?
12
- error(400, "Must specify '#{identity_key}' in JSON")
13
+ error(400, "Must specify #{identity_keys.map { |k| k.inspect }.join(' or ')} in JSON")
13
14
  elsif exists_data_dir?(request, request.rest_path[0..1] + ['data', name])
14
15
  error(409, "Object already exists")
15
16
  else
16
- data_store.create_dir(request.rest_path[0..1] + ['data'], name, :recursive)
17
+ create_data_dir(request, request.rest_path[0..1] + ['data'], name, :recursive)
17
18
  json_response(201, {"uri" => "#{build_uri(request.base_uri, request.rest_path + [name])}"})
18
19
  end
19
20
  end
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/endpoints/cookbooks_base'
3
3
 
4
4
  module ChefZero
@@ -7,7 +7,7 @@ module ChefZero
7
7
  class EnvironmentCookbookEndpoint < CookbooksBase
8
8
  def get(request)
9
9
  cookbook_name = request.rest_path[5]
10
- environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
10
+ environment = JSON.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
11
11
  constraints = environment['cookbook_versions'] || {}
12
12
  cookbook_versions = list_data(request, request.rest_path[0..1] + request.rest_path[4..5])
13
13
  if request.query_params['num_versions'] == 'all'
@@ -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
 
@@ -12,7 +12,7 @@ module ChefZero
12
12
 
13
13
  # Get the list of cookbooks and versions desired by the runlist
14
14
  desired_versions = {}
15
- run_list = FFI_Yajl::Parser.parse(request.body, :create_additions => false)['run_list']
15
+ run_list = JSON.parse(request.body, :create_additions => false)['run_list']
16
16
  run_list.each do |run_list_entry|
17
17
  if run_list_entry =~ /(.+)::.+\@(.+)/ || run_list_entry =~ /(.+)\@(.+)/
18
18
  raise RestErrorResponse.new(412, "No such cookbook: #{$1}") if !cookbook_names.include?($1)
@@ -26,7 +26,7 @@ module ChefZero
26
26
  end
27
27
 
28
28
  # Filter by environment constraints
29
- environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
29
+ environment = JSON.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
30
30
  environment_constraints = environment['cookbook_versions'] || {}
31
31
 
32
32
  desired_versions.each_key do |name|
@@ -48,8 +48,8 @@ module ChefZero
48
48
 
49
49
  result = {}
50
50
  solved.each_pair do |name, versions|
51
- cookbook = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ['cookbooks', name, versions[0]]), :create_additions => false)
52
- result[name] = DataNormalizer.normalize_cookbook(self, request.rest_path[0..1], cookbook, name, versions[0], request.base_uri, 'MIN')
51
+ cookbook = JSON.parse(get_data(request, request.rest_path[0..1] + ['cookbooks', name, versions[0]]), :create_additions => false)
52
+ result[name] = ChefData::DataNormalizer.normalize_cookbook(self, request.rest_path[0..1], cookbook, name, versions[0], request.base_uri, 'MIN')
53
53
  end
54
54
  json_response(200, result)
55
55
  end
@@ -74,7 +74,7 @@ module ChefZero
74
74
  new_unsolved = unsolved[1..-1]
75
75
 
76
76
  # Pick this cookbook, and add dependencies
77
- cookbook_obj = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ['cookbooks', solve_for, desired_version]), :create_additions => false)
77
+ cookbook_obj = JSON.parse(get_data(request, request.rest_path[0..1] + ['cookbooks', solve_for, desired_version]), :create_additions => false)
78
78
  cookbook_metadata = cookbook_obj['metadata'] || {}
79
79
  cookbook_dependencies = cookbook_metadata['dependencies'] || {}
80
80
  dep_not_found = false
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/endpoints/cookbooks_base'
3
3
 
4
4
  module ChefZero
@@ -6,7 +6,7 @@ module ChefZero
6
6
  # /environments/NAME/cookbooks
7
7
  class EnvironmentCookbooksEndpoint < CookbooksBase
8
8
  def get(request)
9
- environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
9
+ environment = JSON.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
10
10
  constraints = environment['cookbook_versions'] || {}
11
11
  if request.query_params['num_versions'] == 'all'
12
12
  num_versions = nil
@@ -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
 
5
5
  module ChefZero
6
6
  module Endpoints
@@ -24,9 +24,9 @@ module ChefZero
24
24
  end
25
25
 
26
26
  def populate_defaults(request, response_json)
27
- response = FFI_Yajl::Parser.parse(response_json, :create_additions => false)
28
- response = DataNormalizer.normalize_environment(response, request.rest_path[3])
29
- FFI_Yajl::Encoder.encode(response, :pretty => true)
27
+ response = JSON.parse(response_json, :create_additions => false)
28
+ response = ChefData::DataNormalizer.normalize_environment(response, request.rest_path[3])
29
+ JSON.pretty_generate(response)
30
30
  end
31
31
  end
32
32
  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
@@ -11,7 +11,7 @@ module ChefZero
11
11
 
12
12
  result = {}
13
13
  list_data(request, request.rest_path[0..1] + ['nodes']).each do |name|
14
- node = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ['nodes', name]), :create_additions => false)
14
+ node = JSON.parse(get_data(request, request.rest_path[0..1] + ['nodes', name]), :create_additions => false)
15
15
  if node['chef_environment'] == request.rest_path[3]
16
16
  result[name] = build_uri(request.base_uri, request.rest_path[0..1] + ['nodes', name])
17
17
  end
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/endpoints/cookbooks_base'
3
3
 
4
4
  module ChefZero
@@ -6,12 +6,12 @@ module ChefZero
6
6
  # /environment/NAME/recipes
7
7
  class EnvironmentRecipesEndpoint < CookbooksBase
8
8
  def get(request)
9
- environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
9
+ environment = JSON.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
10
10
  constraints = environment['cookbook_versions'] || {}
11
11
  result = []
12
12
  filter_cookbooks(all_cookbooks_list(request), constraints, 1) do |name, versions|
13
13
  if versions.size > 0
14
- cookbook = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ['cookbooks', name, versions[0]]), :create_additions => false)
14
+ cookbook = JSON.parse(get_data(request, request.rest_path[0..1] + ['cookbooks', name, versions[0]]), :create_additions => false)
15
15
  result += recipe_names(name, cookbook)
16
16
  end
17
17
  end
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/endpoints/cookbooks_base'
3
3
 
4
4
  module ChefZero
@@ -18,7 +18,7 @@ module ChefZero
18
18
  # Verify that the environment exists
19
19
  get_data(request, environment_path)
20
20
 
21
- role = FFI_Yajl::Parser.parse(get_data(request, role_path), :create_additions => false)
21
+ role = JSON.parse(get_data(request, role_path), :create_additions => false)
22
22
  environment_name = environment_path[3]
23
23
  if environment_name == '_default'
24
24
  run_list = role['run_list']
@@ -14,7 +14,7 @@ module ChefZero
14
14
  end
15
15
 
16
16
  def put(request)
17
- data_store.set(request.rest_path, request.body, :create, :create_dir)
17
+ data_store.set(request.rest_path, request.body, :create, :create_dir, :requestor => request.requestor)
18
18
  json_response(200, {})
19
19
  end
20
20
  end
@@ -0,0 +1,20 @@
1
+ require 'json'
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/groups/NAME
8
+ class GroupEndpoint < RestObjectEndpoint
9
+ def initialize(server)
10
+ super(server, %w(id groupname))
11
+ end
12
+
13
+ def populate_defaults(request, response_json)
14
+ group = JSON.parse(response_json, :create_additions => false)
15
+ group = ChefData::DataNormalizer.normalize_group(group, request.rest_path[3], request.rest_path[1])
16
+ JSON.pretty_generate(group)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ require 'json'
2
+ require 'chef_zero/endpoints/rest_list_endpoint'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /organizations/ORG/groups/NAME
7
+ class GroupsEndpoint < RestListEndpoint
8
+ def initialize(server)
9
+ super(server, %w(id groupname))
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /license
7
+ class LicenseEndpoint < RestBase
8
+ MAX_NODE_COUNT = 25
9
+
10
+ def get(request)
11
+ node_count = 0
12
+ list_data(request, [ 'organizations' ]).each do |orgname|
13
+ node_count += list_data(request, [ 'organizations', orgname, 'nodes' ]).size
14
+ end
15
+
16
+ json_response(200, {
17
+ "limit_exceeded" => (node_count > MAX_NODE_COUNT) ? true : false,
18
+ "node_license" => MAX_NODE_COUNT,
19
+ "node_count" => node_count,
20
+ "upgrade_url" => 'http://blah.com'
21
+ })
22
+ end
23
+ end
24
+ end
25
+ end
@@ -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
  # /nodes/ID
8
8
  class NodeEndpoint < RestObjectEndpoint
9
9
  def populate_defaults(request, response_json)
10
- node = FFI_Yajl::Parser.parse(response_json, :create_additions => false)
11
- node = DataNormalizer.normalize_node(node, request.rest_path[3])
12
- FFI_Yajl::Encoder.encode(node, :pretty => true)
10
+ node = JSON.parse(response_json, :create_additions => false)
11
+ node = ChefData::DataNormalizer.normalize_node(node, request.rest_path[3])
12
+ JSON.pretty_generate(node)
13
13
  end
14
14
  end
15
15
  end
@@ -1,10 +1,10 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
 
3
3
  module ChefZero
4
4
  module Endpoints
5
5
  class NotFoundEndpoint
6
6
  def call(request)
7
- return [404, {"Content-Type" => "application/json"}, FFI_Yajl::Encoder.encode({"error" => ["Object not found: #{request.env['REQUEST_PATH']}"]}, :pretty => true)]
7
+ return [404, {"Content-Type" => "application/json"}, JSON.pretty_generate({"error" => ["Object not found: #{request.env['REQUEST_PATH']}"]})]
8
8
  end
9
9
  end
10
10
  end
@@ -0,0 +1,22 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /organizations/ORG/association_requests/ID
7
+ class OrganizationAssociationRequestEndpoint < RestBase
8
+ def delete(request)
9
+ orgname = request.rest_path[1]
10
+ id = request.rest_path[3]
11
+ if id !~ /(.+)-#{orgname}$/
12
+ raise HttpErrorResponse.new(404, "Invalid ID #{id}. Must be of the form username-#{orgname}")
13
+ end
14
+ username = $1
15
+ path = request.rest_path[0..-2] + [username]
16
+ data = JSON.parse(get_data(request, path), :create_additions => false)
17
+ delete_data(request, path)
18
+ json_response(200, { "id" => id, "username" => username })
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /organizations/ORG/association_requests
7
+ class OrganizationAssociationRequestsEndpoint < RestBase
8
+ def post(request)
9
+ json = JSON.parse(request.body, :create_additions => false)
10
+ username = json['user']
11
+ orgname = request.rest_path[1]
12
+ id = "#{username}-#{orgname}"
13
+
14
+ if exists_data?(request, [ 'organizations', orgname, 'users', username ])
15
+ raise RestErrorResponse.new(409, "User #{username} is already in organization #{orgname}")
16
+ end
17
+
18
+ create_data(request, request.rest_path, username, '{}')
19
+ json_response(201, { "uri" => build_uri(request.base_uri, request.rest_path + [ id ]) })
20
+ end
21
+
22
+ def get(request)
23
+ orgname = request.rest_path[1]
24
+ result = list_data(request).map { |username| { "id" => "#{username}-#{orgname}", 'username' => username } }
25
+ json_response(200, result)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /organizations/NAME/authenticate_user
7
+ class OrganizationAuthenticateUserEndpoint < RestBase
8
+ def post(request)
9
+ request_json = JSON.parse(request.body, :create_additions => false)
10
+ name = request_json['name']
11
+ password = request_json['password']
12
+ begin
13
+ user = data_store.get(request.rest_path[0..-2] + ['users', name])
14
+ user = JSON.parse(user, :create_additions => false)
15
+ verified = user['password'] == password
16
+ rescue DataStore::DataNotFoundError
17
+ verified = false
18
+ end
19
+ json_response(200, {
20
+ 'name' => name,
21
+ 'verified' => !!verified
22
+ })
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,41 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /organizations/NAME
7
+ class OrganizationEndpoint < RestBase
8
+ def get(request)
9
+ org = get_data(request, request.rest_path + [ 'org' ])
10
+ already_json_response(200, populate_defaults(request, org))
11
+ end
12
+
13
+ def put(request)
14
+ org = JSON.parse(get_data(request, request.rest_path + [ 'org' ]), :create_additions => false)
15
+ new_org = JSON.parse(request.body, :create_additions => false)
16
+ new_org.each do |key, value|
17
+ org[key] = value
18
+ end
19
+ org = JSON.pretty_generate(org)
20
+ if new_org['name'] != request.rest_path[-1]
21
+ # This is a rename
22
+ return error(400, "Cannot rename org #{request.rest_path[-1]} to #{new_org['name']}: rename not supported for orgs")
23
+ end
24
+ set_data(request, request.rest_path + [ 'org' ], org)
25
+ json_response(200, "uri" => "#{build_uri(request.base_uri, request.rest_path)}")
26
+ end
27
+
28
+ def delete(request)
29
+ org = get_data(request, request.rest_path + [ 'org' ])
30
+ delete_data_dir(request, request.rest_path)
31
+ already_json_response(200, populate_defaults(request, org))
32
+ end
33
+
34
+ def populate_defaults(request, response_json)
35
+ org = JSON.parse(response_json, :create_additions => false)
36
+ org = ChefData::DataNormalizer.normalize_organization(org, request.rest_path[1])
37
+ JSON.pretty_generate(org)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,48 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /organizations/ORG/users/NAME
7
+ class OrganizationUserEndpoint < RestBase
8
+ def get(request)
9
+ username = request.rest_path[3]
10
+ get_data(request) # 404 if user is not in org
11
+ user = get_data(request, [ 'users', username ])
12
+ user = JSON.parse(user, :create_additions => false)
13
+ json_response(200, ChefData::DataNormalizer.normalize_user(user, username, ['username'], server.options[:osc_compat], request.method))
14
+ end
15
+
16
+ def delete(request)
17
+ user = get_data(request)
18
+ delete_data(request)
19
+ user = JSON.parse(user, :create_additions => false)
20
+ json_response(200, ChefData::DataNormalizer.normalize_user(user, request.rest_path[3], ['username'], server.options[:osc_compat]))
21
+ end
22
+
23
+ def post(request)
24
+ orgname = request.rest_path[1]
25
+ username = request.rest_path[3]
26
+
27
+ users = get_data(request, [ 'organizations', orgname, 'groups', 'users' ])
28
+ users = JSON.parse(users, :create_additions => false)
29
+
30
+ create_data(request, [ 'organizations', orgname, 'users' ], username, '{}')
31
+
32
+ # /organizations/ORG/association_requests/USERNAME-ORG
33
+ begin
34
+ delete_data(request, [ 'organizations', orgname, 'association_requests', "#{username}-#{orgname}"], :data_store_exceptions)
35
+ rescue DataStore::DataNotFoundError
36
+ end
37
+
38
+ # Add the user to the users group if it isn't already there
39
+ if !users['users'] || !users['users'].include?(username)
40
+ users['users'] ||= []
41
+ users['users'] |= [ username ]
42
+ set_data(request, [ 'organizations', orgname, 'groups', 'users' ], JSON.pretty_generate(users))
43
+ end
44
+ json_response(200, {})
45
+ end
46
+ end
47
+ end
48
+ end