summaryrefslogtreecommitdiff
path: root/lib/chef_zero/endpoints/actor_endpoint.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chef_zero/endpoints/actor_endpoint.rb')
-rw-r--r--lib/chef_zero/endpoints/actor_endpoint.rb124
1 files changed, 103 insertions, 21 deletions
diff --git a/lib/chef_zero/endpoints/actor_endpoint.rb b/lib/chef_zero/endpoints/actor_endpoint.rb
index 1572ac1..a491965 100644
--- a/lib/chef_zero/endpoints/actor_endpoint.rb
+++ b/lib/chef_zero/endpoints/actor_endpoint.rb
@@ -8,15 +8,26 @@ module ChefZero
# /organizations/ORG/users/NAME
# /users/NAME
class ActorEndpoint < RestObjectEndpoint
+ DEFAULT_PUBLIC_KEY_NAME = "default"
+ DEFAULT_PUBLIC_KEY_EXPIRATION_DATE = "infinity"
+
def delete(request)
result = super
+ username = request.rest_path[1]
+
if request.rest_path[0] == 'users'
list_data(request, [ 'organizations' ]).each do |org|
begin
- delete_data(request, [ 'organizations', org, 'users', request.rest_path[1] ], :data_store_exceptions)
+ delete_data(request, [ 'organizations', org, 'users', username ], :data_store_exceptions)
rescue DataStore::DataNotFoundError
end
end
+
+ begin
+ path = [ 'user_keys', username ]
+ delete_data_dir(request, path, :data_store_exceptions)
+ rescue DataStore::DataNotFoundError
+ end
end
result
end
@@ -24,43 +35,46 @@ module ChefZero
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?
+
+ public_key = request_body.delete('public_key')
+
+ if public_key.nil?
# If public_key is null, then don't overwrite it. Weird patchiness.
body_modified = true
- request_body.delete('public_key')
else
updating_public_key = true
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
- request.body = patch_request_body(request)
+ request.body = patch_request_body(request, except: :public_key)
result = super(request)
# Inject private_key into response, delete public_key/password if applicable
if result[0] == 200 || result[0] == 201
+ username = identity_key_value(request) || request.rest_path[-1]
+
+ # TODO Implement for clients
+ if request.rest_path[2] != 'clients' && is_rename?(request)
+ rename_user_keys!(request, username)
+ 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', username ])
}
else
response = FFI_Yajl::Parser.parse(result[2], :create_additions => false)
@@ -70,25 +84,93 @@ module ChefZero
response['private_key'] = private_key ? private_key : false
else
response['private_key'] = private_key if private_key
+
+ if updating_public_key
+ update_user_default_key!(request, public_key)
+ end
+ end
+
+ if request.rest_path[2] == 'users' && !updating_public_key
+ response.delete('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
end
end
+ private
+
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])
- else
- response = ChefData::DataNormalizer.normalize_user(response, request.rest_path[3], identity_keys, server.options[:osc_compat], request.method)
- end
+
+ response =
+ if request.rest_path[2] == 'clients'
+ ChefData::DataNormalizer.normalize_client(response, request.rest_path[3], request.rest_path[1])
+ else
+ public_key = get_user_default_public_key(request, response['username'])
+
+ if public_key
+ response['public_key'] = public_key
+ end
+
+ ChefData::DataNormalizer.normalize_user(response, request.rest_path[3], identity_keys, server.options[:osc_compat], request.method)
+ end
+
FFI_Yajl::Encoder.encode(response, :pretty => true)
end
+
+ # Returns the user's default public_key from user_keys store
+ def get_user_default_public_key(request, username)
+ path = [ "user_keys", username, "keys", DEFAULT_PUBLIC_KEY_NAME ]
+ key_json = get_data(request, path, :nil)
+ return unless key_json
+
+ key_data = FFI_Yajl::Parser.parse(key_json, create_additions: false)
+ key_data && key_data["public_key"]
+ end
+
+ # Move key data to new path
+ def rename_user_keys!(request, new_username)
+ orig_username = request.rest_path[-1]
+ orig_user_keys_path = [ 'user_keys', orig_username, 'keys' ]
+ new_user_keys_path = [ 'user_keys', new_username, 'keys' ]
+
+ user_key_names = list_data(request, orig_user_keys_path, :data_store_exceptions)
+
+ user_key_names.each do |key_name|
+ # Get old data
+ orig_path = orig_user_keys_path + [ key_name ]
+ data = get_data(request, orig_path, :data_store_exceptions)
+
+ # Copy data to new path
+ create_data(
+ request,
+ new_user_keys_path, key_name,
+ data,
+ :create_dir
+ )
+ end
+
+ # Delete original data
+ delete_data_dir(request, orig_user_keys_path, :data_store_exceptions)
+ end
+
+ def update_user_default_key!(request, public_key)
+ username = request.rest_path[1]
+ path = [ "user_keys", username, "keys", DEFAULT_PUBLIC_KEY_NAME ]
+
+ data = FFI_Yajl::Encoder.encode(
+ "name" => DEFAULT_PUBLIC_KEY_NAME,
+ "public_key" => public_key,
+ "expiration_date" => DEFAULT_PUBLIC_KEY_EXPIRATION_DATE
+ )
+
+ set_data(request, path, data, :create, :data_store_exceptions)
+ end
end
end
end