diff options
author | Jordan Running <jr@getchef.com> | 2016-02-11 13:06:56 -0600 |
---|---|---|
committer | Jordan Running <jr@getchef.com> | 2016-02-24 13:35:19 -0600 |
commit | 2469894eab12f24893916b571a981e082dfe97df (patch) | |
tree | bc657d22f7f41dad46a68f9825189c2dd20053b9 /lib/chef_zero/endpoints/actor_endpoint.rb | |
parent | 86e99a48cc39a0b5c931c29fbfef9e196252c9c2 (diff) | |
download | chef-zero-2469894eab12f24893916b571a981e082dfe97df.tar.gz |
Make user and client keys endpoints pass Pedant specs
- Implement ActorKeyEndpoint, ActorKeysEndpoint.
- Implement user, client keys in `ActorEndpoint#delete`, `#put`.
- RestBase
- Fix RestErrorResponse exceptions to report actual `rest_path`
instead associated with the failed data store operation instead of
`request.rest_path`.
- Move `json_response`, `already_json_response` args `request_version`
and `response_version` into options hash; add docs.
- DataError, RestErrorResponse: Pass useful message text to `super`.
- RestRouter: Clean up logging
- Print request methods, paths and bodies more readably for log_level >= INFO.
- Pretty-print RestRequest objects (only printed when log_level == DEBUG).
- Server: Change default log_level to `:warn` (to enable logging cleanup above).
- `Rakefile`, `spec/run_oc_pedant.rb`
- Consume RSpec, Pedant options from `ENV['RSPEC_OPTS']`, `ENV['PEDANT_OPTS']` (see `rake -D`).
- Consume `ENV['LOG_LEVEL'` (see `rake -D`).
- Clean up ChefZero::Server default opts and move duplicated logic to `start_chef_server` method.
Diffstat (limited to 'lib/chef_zero/endpoints/actor_endpoint.rb')
-rw-r--r-- | lib/chef_zero/endpoints/actor_endpoint.rb | 113 |
1 files changed, 96 insertions, 17 deletions
diff --git a/lib/chef_zero/endpoints/actor_endpoint.rb b/lib/chef_zero/endpoints/actor_endpoint.rb index 1572ac1..12fbe11 100644 --- a/lib/chef_zero/endpoints/actor_endpoint.rb +++ b/lib/chef_zero/endpoints/actor_endpoint.rb @@ -10,6 +10,7 @@ module ChefZero class ActorEndpoint < RestObjectEndpoint def delete(request) result = super + if request.rest_path[0] == 'users' list_data(request, [ 'organizations' ]).each do |org| begin @@ -18,12 +19,15 @@ module ChefZero end end end + + delete_actor_keys!(request) result end def put(request) # Find out if we're updating the public key. request_body = FFI_Yajl::Parser.parse(request.body, :create_additions => false) + if request_body['public_key'].nil? # If public_key is null, then don't overwrite it. Weird patchiness. body_modified = true @@ -33,17 +37,17 @@ module ChefZero end # Generate private_key if requested. - if request_body.has_key?('private_key') + if request_body.key?('private_key') body_modified = true - if request_body['private_key'] + + if request_body.delete('private_key') private_key, public_key = server.gen_key_pair updating_public_key = true request_body['public_key'] = public_key end - request_body.delete('private_key') end - # Save request + # Put modified body back in `request.body` request.body = FFI_Yajl::Encoder.encode(request_body, :pretty => true) if body_modified # PUT /clients is patchy @@ -53,27 +57,29 @@ module ChefZero # Inject private_key into response, delete public_key/password if applicable if result[0] == 200 || result[0] == 201 + client_or_user_name = identity_key_value(request) || request.rest_path[-1] + + if is_rename?(request) + rename_keys!(request, client_or_user_name) + end + if request.rest_path[0] == 'users' - key = nil - identity_keys.each do |identity_key| - key ||= request_body[identity_key] - end - key ||= request.rest_path[-1] response = { - 'uri' => build_uri(request.base_uri, [ 'users', key ]) + 'uri' => build_uri(request.base_uri, [ 'users', client_or_user_name ]) } else response = FFI_Yajl::Parser.parse(result[2], :create_additions => false) end - if request.rest_path[2] == 'clients' + if client?(request) response['private_key'] = private_key ? private_key : false else response['private_key'] = private_key if private_key + response.delete('public_key') unless updating_public_key end - response.delete('public_key') if !updating_public_key && request.rest_path[2] == 'users' response.delete('password') + json_response(result[0], response) else result @@ -81,13 +87,86 @@ module ChefZero end def populate_defaults(request, response_json) - response = FFI_Yajl::Parser.parse(response_json, :create_additions => false) - if request.rest_path[2] == 'clients' - response = ChefData::DataNormalizer.normalize_client(response,request.rest_path[3], request.rest_path[1]) + response = FFI_Yajl::Parser.parse(response_json, create_additions: false) + + populated_response = + if client?(request) + ChefData::DataNormalizer.normalize_client( + response, + response["name"] || request.rest_path[-1], + request.rest_path[1] + ) + else + ChefData::DataNormalizer.normalize_user( + response, + response["username"] || request.rest_path[-1], + identity_keys, + server.options[:osc_compat], + request.method + ) + end + + FFI_Yajl::Encoder.encode(populated_response, pretty: true) + end + + private + + # Move key data to new path + def rename_keys!(request, new_client_or_user_name) + orig_keys_path = keys_path_base(request) + new_keys_path = orig_keys_path.dup + .tap {|path| path[-2] = new_client_or_user_name } + + key_names = list_data_or_else(request, orig_keys_path, nil) + return unless key_names # No keys to move + + key_names.each do |key_name| + # Get old data + orig_path = [ *orig_keys_path, key_name ] + data = get_data(request, orig_path, :data_store_exceptions) + + # Copy data to new path + create_data( + request, + new_keys_path, key_name, + data, + :create_dir + ) + end + + # Delete original data + delete_data_dir(request, orig_keys_path, :recursive, :data_store_exceptions) + end + + def delete_actor_keys!(request) + path = keys_path_base(request)[0..-2] + delete_data_dir(request, path, :recursive, :data_store_exceptions) + rescue DataStore::DataNotFoundError + end + + def client?(request, rest_path=nil) + rest_path ||= request.rest_path + request.rest_path[2] == "clients" + end + + # Return the data store keys path for the request client or user, e.g. + # + # [ "organizations", <org>, "client_keys", <client>, "keys" ] + # + # Or: + # + # [ "user_keys", <user>, "keys" ] + # + def keys_path_base(request, client_or_user_name=nil) + rest_path = (rest_path || request.rest_path).dup + rest_path[-1] = client_or_user_name if client_or_user_name + + if client?(request, rest_path) + [ *rest_path[0..1], "client_keys" ] else - response = ChefData::DataNormalizer.normalize_user(response, request.rest_path[3], identity_keys, server.options[:osc_compat], request.method) + [ "user_keys" ] end - FFI_Yajl::Encoder.encode(response, :pretty => true) + .push(rest_path.last, "keys") end end end |