summaryrefslogtreecommitdiff
path: root/lib/chef_zero/endpoints
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chef_zero/endpoints')
-rw-r--r--lib/chef_zero/endpoints/actor_default_key_endpoint.rb70
-rw-r--r--lib/chef_zero/endpoints/actor_endpoint.rb4
-rw-r--r--lib/chef_zero/endpoints/actor_key_endpoint.rb69
-rw-r--r--lib/chef_zero/endpoints/actor_keys_endpoint.rb30
-rw-r--r--lib/chef_zero/endpoints/rest_object_endpoint.rb2
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