diff options
author | Jordan Running <jr@getchef.com> | 2016-02-18 15:43:56 -0600 |
---|---|---|
committer | Jordan Running <jr@getchef.com> | 2016-02-24 14:16:30 -0600 |
commit | b0971ce66e69cefd6e148a648f01667c0146e577 (patch) | |
tree | 87f2d5b56f1fe50f27d69150133f5201a12ae527 /lib/chef_zero/endpoints | |
parent | 2469894eab12f24893916b571a981e082dfe97df (diff) | |
download | chef-zero-b0971ce66e69cefd6e148a648f01667c0146e577.tar.gz |
Move default keys logic into ActorDefaultKeyEndpoint; fix #putjr/pedant-keys-2
Diffstat (limited to 'lib/chef_zero/endpoints')
-rw-r--r-- | lib/chef_zero/endpoints/actor_default_key_endpoint.rb | 70 | ||||
-rw-r--r-- | lib/chef_zero/endpoints/actor_endpoint.rb | 4 | ||||
-rw-r--r-- | lib/chef_zero/endpoints/actor_key_endpoint.rb | 69 | ||||
-rw-r--r-- | lib/chef_zero/endpoints/actor_keys_endpoint.rb | 30 | ||||
-rw-r--r-- | lib/chef_zero/endpoints/rest_object_endpoint.rb | 2 |
5 files changed, 106 insertions, 69 deletions
diff --git a/lib/chef_zero/endpoints/actor_default_key_endpoint.rb b/lib/chef_zero/endpoints/actor_default_key_endpoint.rb new file mode 100644 index 0000000..f63ffb9 --- /dev/null +++ b/lib/chef_zero/endpoints/actor_default_key_endpoint.rb @@ -0,0 +1,70 @@ +require 'chef_zero/rest_base' + +module ChefZero + module Endpoints + # ActorDefaultKeyEndpoint + # + # This class handles DELETE/GET/PUT requests for client/user default public + # keys, i.e. requests with identity key "default". All others are handled + # by ActorKeyEndpoint. + # + # Default public keys are stored with the actor (client or user) instead of + # under user/client_keys. Handling those in a separate endpoint offloads + # the branching logic onto the router rather than branching in every + # endpoint method (`if request.rest_path[-1] == "default" ...`). + # + # /users/USER/keys/default + # /organizations/ORG/clients/CLIENT/keys/default + class ActorDefaultKeyEndpoint < RestBase + DEFAULT_PUBLIC_KEY_NAME = "default".freeze + + def get(request) + # 404 if actor doesn't exist + actor_data = get_actor_data(request) + json_response(200, default_public_key_from_actor(actor_data)) + end + + def delete(request) + path = actor_path(request) + actor_data = get_actor_data(request) # 404 if actor doesn't exist + + default_public_key = delete_actor_default_public_key!(request, path, actor_data) + json_response(200, default_public_key) + end + + def put(request) + # 404 if actor doesn't exist + actor_data = get_actor_data(request) + + new_public_key = parse_json(request.body)["public_key"] + actor_data["public_key"] = new_public_key + + set_data(request, actor_path(request), to_json(actor_data)) + end + + private + + def actor_path(request) + return request.rest_path[0..3] if request.rest_path[2] == "clients" + request.rest_path[0..1] + end + + def get_actor_data(request) + path = actor_path(request) + parse_json(get_data(request, path)) + end + + def default_public_key_from_actor(actor_data) + { "name" => DEFAULT_PUBLIC_KEY_NAME, + "public_key" => actor_data["public_key"], + "expiration_date" => "infinity" } + end + + def delete_actor_default_public_key!(request, path, actor_data) + new_actor_data = actor_data.merge("public_key" => nil) + set_data(request, path, to_json(new_actor_data)) + default_public_key_from_actor(actor_data) + end + end + end +end diff --git a/lib/chef_zero/endpoints/actor_endpoint.rb b/lib/chef_zero/endpoints/actor_endpoint.rb index 12fbe11..446c196 100644 --- a/lib/chef_zero/endpoints/actor_endpoint.rb +++ b/lib/chef_zero/endpoints/actor_endpoint.rb @@ -87,7 +87,7 @@ module ChefZero end def populate_defaults(request, response_json) - response = FFI_Yajl::Parser.parse(response_json, create_additions: false) + response = parse_json(response_json) populated_response = if client?(request) @@ -106,7 +106,7 @@ module ChefZero ) end - FFI_Yajl::Encoder.encode(populated_response, pretty: true) + to_json(populated_response) end private diff --git a/lib/chef_zero/endpoints/actor_key_endpoint.rb b/lib/chef_zero/endpoints/actor_key_endpoint.rb index d45570d..f2b65ed 100644 --- a/lib/chef_zero/endpoints/actor_key_endpoint.rb +++ b/lib/chef_zero/endpoints/actor_key_endpoint.rb @@ -1,39 +1,27 @@ -require 'ffi_yajl' require 'chef_zero/rest_base' module ChefZero module Endpoints + # ActorKeyEndpoint + # + # This class handles DELETE/GET/PUT requests for all client/user keys + # **except** default public keys, i.e. requests with identity key + # "default". Those are handled by ActorDefaultKeyEndpoint. See that class + # for more information. + # # /users/USER/keys/NAME # /organizations/ORG/clients/CLIENT/keys/NAME class ActorKeyEndpoint < RestBase - DEFAULT_PUBLIC_KEY_NAME = "default".freeze - def get(request) - # Try to get the actor so a 404 is returned if it doesn't exist - actor_json = get_actor_json(request) - - if request.rest_path[-1] == DEFAULT_PUBLIC_KEY_NAME - actor_data = FFI_Yajl::Parser.parse(actor_json, create_additions: false) - default_public_key = default_public_key_from_actor(actor_data) - return json_response(200, default_public_key) - end - + validate_actor!(request) key_path = data_path(request) already_json_response(200, get_data(request, key_path)) end def delete(request) - # Try to get the actor so a 404 is returned if it doesn't exist - actor_json = get_actor_json(request) - - if request.rest_path[-1] == DEFAULT_PUBLIC_KEY_NAME - actor_data = FFI_Yajl::Parser.parse(actor_json, create_additions: false) - default_public_key = delete_actor_default_public_key!(request, actor_data) - return json_response(200, default_public_key) - end + validate_actor!(request) # 404 if actor doesn't exist key_path = data_path(request) - data = get_data(request, key_path) delete_data(request, key_path) @@ -41,17 +29,15 @@ module ChefZero end def put(request) - # We grab the old data to trigger a 404 if it doesn't exist - get_data(request, data_path(request)) - - set_data(request, path, request.body) + validate_actor!(request) # 404 if actor doesn't exist + set_data(request, data_path(request), request.body) end private # Returns the keys data store path, which is the same as - # `request.rest_path` except with "user_keys" instead of "users" or - # "client_keys" instead of "clients." + # `request.rest_path` except with "client_keys" instead of "clients" or + # "user_keys" instead of "users." def data_path(request) request.rest_path.dup.tap do |path| if client?(request) @@ -62,36 +48,15 @@ module ChefZero end end - def default_public_key_from_actor(actor_data) - { "name" => DEFAULT_PUBLIC_KEY_NAME, - "public_key" => actor_data["public_key"], - "expiration_date" => "infinity" } - end - - def delete_actor_default_public_key!(request, actor_data) - new_actor_data = actor_data.merge("public_key" => nil) - - set_data( - request, - actor_path(request), - FFI_Yajl::Encoder.encode(new_actor_data, pretty: true) - ) - - default_public_key_from_actor(actor_data) - end - - def get_actor_json(request) - get_data(request, actor_path(request)) + # Raises RestErrorResponse (404) if actor doesn't exist + def validate_actor!(request) + actor_path = request.rest_path[ client?(request) ? 0..3 : 0..1 ] + get_data(request, actor_path) end def client?(request) request.rest_path[2] == "clients" end - - def actor_path(request) - return request.rest_path[0..3] if client?(request) - request.rest_path[0..1] - end end end end diff --git a/lib/chef_zero/endpoints/actor_keys_endpoint.rb b/lib/chef_zero/endpoints/actor_keys_endpoint.rb index 8bf3981..ba91a6b 100644 --- a/lib/chef_zero/endpoints/actor_keys_endpoint.rb +++ b/lib/chef_zero/endpoints/actor_keys_endpoint.rb @@ -1,4 +1,3 @@ -require 'ffi_yajl' require 'chef_zero/rest_base' module ChefZero @@ -13,8 +12,7 @@ module ChefZero path = data_path(request) # Get actor or 404 if it doesn't exist - actor_path = request.rest_path[ client?(request) ? 0..3 : 0..1 ] - actor_json = get_data(request, actor_path) + actor_json = get_data(request, actor_path(request)) key_names = list_data_or_else(request, path, []) key_names.unshift(DEFAULT_PUBLIC_KEY_NAME) if actor_has_default_public_key?(actor_json) @@ -27,11 +25,10 @@ module ChefZero end def post(request) - request_body = FFI_Yajl::Parser.parse(request.body, create_additions: false) + request_body = parse_json(request.body) # Try loading the client or user so a 404 is returned if it doesn't exist - actor_path = request.rest_path[ client?(request) ? 0..3 : 0..1 ] - actor_json = get_data(request, actor_path) + actor_json = get_data(request, actor_path(request)) generate_keys = request_body["public_key"].nil? @@ -44,7 +41,7 @@ module ChefZero key_name = request_body["name"] if key_name == DEFAULT_PUBLIC_KEY_NAME - store_actor_default_public_key!(request, actor_path, actor_json, public_key) + store_actor_default_public_key!(request, actor_json, public_key) else store_actor_public_key!(request, key_name, public_key, request_body["expiration_date"]) end @@ -59,7 +56,7 @@ module ChefZero private def store_actor_public_key!(request, name, public_key, expiration_date) - data = FFI_Yajl::Encoder.encode( + data = to_json( "name" => name, "public_key" => public_key, "expiration_date" => expiration_date @@ -68,15 +65,16 @@ module ChefZero create_data(request, data_path(request), name, data, :create_dir) end - def store_actor_default_public_key!(request, actor_path, actor_json, public_key) - actor_data = FFI_Yajl::Parser.parse(actor_json, create_additions: false) + def store_actor_default_public_key!(request, actor_json, public_key) + actor_data = parse_json(actor_json) if actor_data["public_key"] raise RestErrorResponse.new(409, "Object already exists: #{key_uri(request, DEFAULT_PUBLIC_KEY_NAME)}") end actor_data["public_key"] = public_key - set_data(request, actor_path, FFI_Yajl::Encoder.encode(actor_data, pretty: true)) + set_data(request, actor_path(request), to_json(actor_data)) + end # Returns the keys data store path, which is the same as @@ -97,7 +95,7 @@ module ChefZero if data_path[-1] == DEFAULT_PUBLIC_KEY_NAME [ DEFAULT_PUBLIC_KEY_NAME, "infinity" ] else - FFI_Yajl::Parser.parse(get_data(request, data_path), create_additions: false) + parse_json(get_data(request, data_path)) .values_at("name", "expiration_date") end @@ -117,9 +115,13 @@ module ChefZero build_uri(request.base_uri, [ *request.rest_path, key_name ]) end + def actor_path(request) + return request.rest_path[0..3] if client?(request) + request.rest_path[0..1] + end + def actor_has_default_public_key?(actor_json) - actor_data = FFI_Yajl::Parser.parse(actor_json, create_additions: false) - !!actor_data["public_key"] + !!parse_json(actor_json)["public_key"] end end end diff --git a/lib/chef_zero/endpoints/rest_object_endpoint.rb b/lib/chef_zero/endpoints/rest_object_endpoint.rb index 95a3122..7e839c0 100644 --- a/lib/chef_zero/endpoints/rest_object_endpoint.rb +++ b/lib/chef_zero/endpoints/rest_object_endpoint.rb @@ -63,7 +63,7 @@ module ChefZero # Get the value of the (first existing) identity key from the request body or nil def identity_key_value(request) - request_json = FFI_Yajl::Parser.parse(request.body, :create_additions => false) + request_json = parse_json(request.body) identity_keys.map { |k| request_json[k] }.compact.first end |