diff --git a/lib/chef_zero/endpoints/actor_default_key_endpoint.rb b/lib/chef_zero/endpoints/actor_default_key_endpoint.rb index f63ffb94..3be1475e 100644 --- a/lib/chef_zero/endpoints/actor_default_key_endpoint.rb +++ b/lib/chef_zero/endpoints/actor_default_key_endpoint.rb @@ -21,6 +21,13 @@ class ActorDefaultKeyEndpoint < RestBase def get(request) # 404 if actor doesn't exist actor_data = get_actor_data(request) + key_data = default_public_key_from_actor(actor_data) + + # 404 if the actor doesn't have a default key + if key_data["public_key"].nil? + raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, request.rest_path)}") + end + json_response(200, default_public_key_from_actor(actor_data)) end diff --git a/lib/chef_zero/endpoints/actor_endpoint.rb b/lib/chef_zero/endpoints/actor_endpoint.rb index 446c196c..28d81311 100644 --- a/lib/chef_zero/endpoints/actor_endpoint.rb +++ b/lib/chef_zero/endpoints/actor_endpoint.rb @@ -8,6 +8,16 @@ module Endpoints # /organizations/ORG/users/NAME # /users/NAME class ActorEndpoint < RestObjectEndpoint + + def get(request) + result = super + user_data = parse_json(result[2]) + + user_data.delete("public_key") unless request.api_v0? + + json_response(200, user_data) + end + def delete(request) result = super @@ -48,7 +58,7 @@ def put(request) end # Put modified body back in `request.body` - request.body = FFI_Yajl::Encoder.encode(request_body, :pretty => true) if body_modified + request.body = to_json(request_body) if body_modified # PUT /clients is patchy request.body = patch_request_body(request) @@ -68,7 +78,7 @@ def put(request) 'uri' => build_uri(request.base_uri, [ 'users', client_or_user_name ]) } else - response = FFI_Yajl::Parser.parse(result[2], :create_additions => false) + response = parse_json(result[2]) end if client?(request) diff --git a/lib/chef_zero/endpoints/actors_endpoint.rb b/lib/chef_zero/endpoints/actors_endpoint.rb index c6c676f9..cc02246f 100644 --- a/lib/chef_zero/endpoints/actors_endpoint.rb +++ b/lib/chef_zero/endpoints/actors_endpoint.rb @@ -9,29 +9,29 @@ def get(request) response = super(request) if request.query_params['email'] - results = FFI_Yajl::Parser.parse(response[2], :create_additions => false) + results = parse_json(response[2]) new_results = {} results.each do |name, url| record = get_data(request, request.rest_path + [ name ], :nil) if record - record = FFI_Yajl::Parser.parse(record, :create_additions => false) + record = parse_json(record) new_results[name] = url if record['email'] == request.query_params['email'] end end - response[2] = FFI_Yajl::Encoder.encode(new_results, :pretty => true) + response[2] = to_json(new_results) end if request.query_params['verbose'] - results = FFI_Yajl::Parser.parse(response[2], :create_additions => false) + results = parse_json(response[2]) results.each do |name, url| record = get_data(request, request.rest_path + [ name ], :nil) if record - record = FFI_Yajl::Parser.parse(record, :create_additions => false) + record = parse_json(record) record = ChefData::DataNormalizer.normalize_user(record, name, identity_keys, server.options[:osc_compat]) results[name] = record end end - response[2] = FFI_Yajl::Encoder.encode(results, :pretty => true) + response[2] = to_json(results) end response end @@ -39,21 +39,47 @@ def get(request) def post(request) # First, find out if the user actually posted a public key. If not, make # one. - request_body = FFI_Yajl::Parser.parse(request.body, :create_additions => false) + request_body = parse_json(request.body) public_key = request_body['public_key'] - if !public_key + + skip_key_create = !request.api_v0? && !request_body["create_key"] + + if !public_key && !skip_key_create private_key, public_key = server.gen_key_pair request_body['public_key'] = public_key - request.body = FFI_Yajl::Encoder.encode(request_body, :pretty => true) + request.body = to_json(request_body) + elsif skip_key_create + request_body['public_key'] = nil + request.body = to_json(request_body) end result = super(request) if result[0] == 201 # If we generated a key, stuff it in the response. - response = FFI_Yajl::Parser.parse(result[2], :create_additions => false) - response['private_key'] = private_key if private_key - response['public_key'] = public_key unless request.rest_path[0] == 'users' + user_data = parse_json(result[2]) + + key_data = {} + key_data['private_key'] = private_key if private_key + key_data['public_key'] = public_key unless request.rest_path[0] == 'users' + + response = + if request.api_v0? + user_data.merge(key_data) + elsif skip_key_create && !public_key + user_data + else + actor_name = request_body["name"] || request_body["username"] || request_body["clientname"] + + relpath_to_default_key = [ actor_name, "keys", "default" ] + key_data["uri"] = build_uri(request.base_uri, request.rest_path + relpath_to_default_key) + key_data["public_key"] = public_key + key_data["name"] = "default" + key_data["expiration_date"] = "infinity" + user_data["chef_key"] = key_data + user_data + end + json_response(201, response) else result diff --git a/lib/chef_zero/endpoints/principal_endpoint.rb b/lib/chef_zero/endpoints/principal_endpoint.rb index b1f4efbe..64c69869 100644 --- a/lib/chef_zero/endpoints/principal_endpoint.rb +++ b/lib/chef_zero/endpoints/principal_endpoint.rb @@ -30,13 +30,22 @@ def get(request) end end if json - json_response(200, { + principal_data = { 'name' => name, 'type' => type, 'public_key' => FFI_Yajl::Parser.parse(json)['public_key'] || PUBLIC_KEY, 'authz_id' => '0'*32, 'org_member' => org_member - }) + } + + response_data = + if request.api_v0? + principal_data + else + { "principals" => [ principal_data ] } + end + + json_response(200, response_data) else error(404, 'Principal not found') end diff --git a/lib/chef_zero/rest_request.rb b/lib/chef_zero/rest_request.rb index 6b37c184..60738cf4 100644 --- a/lib/chef_zero/rest_request.rb +++ b/lib/chef_zero/rest_request.rb @@ -2,6 +2,9 @@ module ChefZero class RestRequest + + ZERO = "0".freeze + def initialize(env, rest_base_prefix = []) @env = env @rest_base_prefix = rest_base_prefix @@ -19,7 +22,11 @@ def base_uri=(value) end def api_version - @env['HTTP_X_OPS_SERVER_API_VERSION'] || 0 + @env['HTTP_X_OPS_SERVER_API_VERSION'] || ZERO + end + + def api_v0? + api_version == ZERO end def requestor diff --git a/spec/run_oc_pedant.rb b/spec/run_oc_pedant.rb index b8c68981..d874fb8b 100644 --- a/spec/run_oc_pedant.rb +++ b/spec/run_oc_pedant.rb @@ -174,7 +174,6 @@ def args_from_env(key) '--skip-usags', # Chef 12 features not yet 100% supported by Chef Zero - '--skip-api-v1', # The universe endpoint is unlikely to ever make sense for Chef Zero '--skip-universe',