chef-zero 15.0.17 → 15.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +36 -31
- data/LICENSE +201 -201
- data/Rakefile +73 -68
- data/bin/chef-zero +111 -111
- data/chef-zero.gemspec +34 -33
- data/lib/chef_zero/chef_data/acl_path.rb +140 -140
- data/lib/chef_zero/chef_data/cookbook_data.rb +237 -237
- data/lib/chef_zero/chef_data/data_normalizer.rb +276 -276
- data/lib/chef_zero/chef_data/default_creator.rb +476 -476
- data/lib/chef_zero/data_store/data_already_exists_error.rb +29 -29
- data/lib/chef_zero/data_store/data_error.rb +32 -32
- data/lib/chef_zero/data_store/data_not_found_error.rb +29 -29
- data/lib/chef_zero/data_store/default_facade.rb +143 -147
- data/lib/chef_zero/data_store/interface_v1.rb +67 -67
- data/lib/chef_zero/data_store/interface_v2.rb +18 -18
- data/lib/chef_zero/data_store/memory_store.rb +33 -33
- data/lib/chef_zero/data_store/memory_store_v2.rb +159 -159
- data/lib/chef_zero/data_store/raw_file_store.rb +143 -143
- data/lib/chef_zero/data_store/v1_to_v2_adapter.rb +150 -150
- data/lib/chef_zero/data_store/v2_to_v1_adapter.rb +105 -105
- data/lib/chef_zero/dist.rb +9 -9
- data/lib/chef_zero/endpoints/acl_endpoint.rb +39 -39
- data/lib/chef_zero/endpoints/acls_endpoint.rb +41 -41
- data/lib/chef_zero/endpoints/actor_default_key_endpoint.rb +78 -78
- data/lib/chef_zero/endpoints/actor_endpoint.rb +184 -184
- data/lib/chef_zero/endpoints/actor_key_endpoint.rb +62 -62
- data/lib/chef_zero/endpoints/actor_keys_endpoint.rb +129 -129
- data/lib/chef_zero/endpoints/actors_endpoint.rb +104 -104
- data/lib/chef_zero/endpoints/authenticate_user_endpoint.rb +32 -32
- data/lib/chef_zero/endpoints/container_endpoint.rb +22 -22
- data/lib/chef_zero/endpoints/containers_endpoint.rb +25 -25
- data/lib/chef_zero/endpoints/controls_endpoint.rb +16 -16
- data/lib/chef_zero/endpoints/cookbook_artifact_endpoint.rb +24 -24
- data/lib/chef_zero/endpoints/cookbook_artifact_identifier_endpoint.rb +68 -68
- data/lib/chef_zero/endpoints/cookbook_artifacts_endpoint.rb +34 -34
- data/lib/chef_zero/endpoints/cookbook_endpoint.rb +39 -39
- data/lib/chef_zero/endpoints/cookbook_version_endpoint.rb +136 -136
- data/lib/chef_zero/endpoints/cookbooks_base.rb +80 -80
- data/lib/chef_zero/endpoints/cookbooks_endpoint.rb +19 -19
- data/lib/chef_zero/endpoints/data_bag_endpoint.rb +45 -45
- data/lib/chef_zero/endpoints/data_bag_item_endpoint.rb +25 -25
- data/lib/chef_zero/endpoints/data_bags_endpoint.rb +23 -23
- data/lib/chef_zero/endpoints/dummy_endpoint.rb +29 -29
- data/lib/chef_zero/endpoints/environment_cookbook_endpoint.rb +24 -24
- data/lib/chef_zero/endpoints/environment_cookbook_versions_endpoint.rb +126 -126
- data/lib/chef_zero/endpoints/environment_cookbooks_endpoint.rb +22 -22
- data/lib/chef_zero/endpoints/environment_endpoint.rb +33 -33
- data/lib/chef_zero/endpoints/environment_nodes_endpoint.rb +23 -23
- data/lib/chef_zero/endpoints/environment_recipes_endpoint.rb +22 -22
- data/lib/chef_zero/endpoints/environment_role_endpoint.rb +36 -36
- data/lib/chef_zero/endpoints/file_store_file_endpoint.rb +22 -22
- data/lib/chef_zero/endpoints/group_endpoint.rb +20 -20
- data/lib/chef_zero/endpoints/groups_endpoint.rb +13 -13
- data/lib/chef_zero/endpoints/license_endpoint.rb +25 -25
- data/lib/chef_zero/endpoints/node_endpoint.rb +34 -34
- data/lib/chef_zero/endpoints/node_identifiers_endpoint.rb +22 -22
- data/lib/chef_zero/endpoints/nodes_endpoint.rb +34 -34
- data/lib/chef_zero/endpoints/not_found_endpoint.rb +11 -11
- data/lib/chef_zero/endpoints/organization_association_request_endpoint.rb +22 -22
- data/lib/chef_zero/endpoints/organization_association_requests_endpoint.rb +30 -30
- data/lib/chef_zero/endpoints/organization_authenticate_user_endpoint.rb +26 -26
- data/lib/chef_zero/endpoints/organization_endpoint.rb +47 -47
- data/lib/chef_zero/endpoints/organization_user_base.rb +15 -15
- data/lib/chef_zero/endpoints/organization_user_default_key_endpoint.rb +16 -16
- data/lib/chef_zero/endpoints/organization_user_endpoint.rb +26 -26
- data/lib/chef_zero/endpoints/organization_user_key_endpoint.rb +17 -17
- data/lib/chef_zero/endpoints/organization_user_keys_endpoint.rb +17 -17
- data/lib/chef_zero/endpoints/organization_users_endpoint.rb +43 -43
- data/lib/chef_zero/endpoints/organization_validator_key_endpoint.rb +20 -20
- data/lib/chef_zero/endpoints/organizations_endpoint.rb +61 -61
- data/lib/chef_zero/endpoints/policies_endpoint.rb +26 -26
- data/lib/chef_zero/endpoints/policy_endpoint.rb +24 -24
- data/lib/chef_zero/endpoints/policy_group_endpoint.rb +46 -46
- data/lib/chef_zero/endpoints/policy_group_policy_endpoint.rb +83 -83
- data/lib/chef_zero/endpoints/policy_groups_endpoint.rb +38 -38
- data/lib/chef_zero/endpoints/policy_revision_endpoint.rb +66 -66
- data/lib/chef_zero/endpoints/policy_revisions_endpoint.rb +15 -15
- data/lib/chef_zero/endpoints/principal_endpoint.rb +55 -55
- data/lib/chef_zero/endpoints/rest_list_endpoint.rb +42 -42
- data/lib/chef_zero/endpoints/rest_object_endpoint.rb +78 -78
- data/lib/chef_zero/endpoints/role_endpoint.rb +16 -16
- data/lib/chef_zero/endpoints/role_environments_endpoint.rb +14 -14
- data/lib/chef_zero/endpoints/sandbox_endpoint.rb +27 -27
- data/lib/chef_zero/endpoints/sandboxes_endpoint.rb +51 -51
- data/lib/chef_zero/endpoints/search_endpoint.rb +208 -208
- data/lib/chef_zero/endpoints/searches_endpoint.rb +18 -18
- data/lib/chef_zero/endpoints/server_api_version_endpoint.rb +14 -14
- data/lib/chef_zero/endpoints/system_recovery_endpoint.rb +30 -30
- data/lib/chef_zero/endpoints/universe_endpoint.rb +15 -15
- data/lib/chef_zero/endpoints/user_association_request_endpoint.rb +41 -41
- data/lib/chef_zero/endpoints/user_association_requests_count_endpoint.rb +19 -19
- data/lib/chef_zero/endpoints/user_association_requests_endpoint.rb +19 -19
- data/lib/chef_zero/endpoints/user_organizations_endpoint.rb +22 -22
- data/lib/chef_zero/endpoints/version_endpoint.rb +13 -13
- data/lib/chef_zero/log.rb +7 -7
- data/lib/chef_zero/rest_base.rb +332 -332
- data/lib/chef_zero/rest_error_response.rb +11 -11
- data/lib/chef_zero/rest_request.rb +84 -88
- data/lib/chef_zero/rest_router.rb +72 -72
- data/lib/chef_zero/rspec.rb +355 -355
- data/lib/chef_zero/server.rb +730 -730
- data/lib/chef_zero/socketless_server_map.rb +92 -93
- data/lib/chef_zero/solr/query/binary_operator.rb +52 -52
- data/lib/chef_zero/solr/query/phrase.rb +23 -23
- data/lib/chef_zero/solr/query/range_query.rb +46 -46
- data/lib/chef_zero/solr/query/regexpable_query.rb +30 -30
- data/lib/chef_zero/solr/query/subquery.rb +37 -37
- data/lib/chef_zero/solr/query/term.rb +45 -45
- data/lib/chef_zero/solr/query/unary_operator.rb +41 -41
- data/lib/chef_zero/solr/solr_doc.rb +53 -53
- data/lib/chef_zero/solr/solr_parser.rb +208 -208
- data/lib/chef_zero/version.rb +3 -3
- data/lib/chef_zero.rb +10 -10
- data/spec/run_oc_pedant.rb +226 -226
- data/spec/search_spec.rb +36 -36
- data/spec/server_spec.rb +96 -96
- data/spec/socketless_server_map_spec.rb +74 -74
- data/spec/support/oc_pedant.rb +149 -149
- data/spec/support/secrets.json +6 -6
- data/spec/support/stickywicket.pem +27 -27
- metadata +35 -18
@@ -1,62 +1,62 @@
|
|
1
|
-
require_relative "../rest_base"
|
2
|
-
|
3
|
-
module ChefZero
|
4
|
-
module Endpoints
|
5
|
-
# ActorKeyEndpoint
|
6
|
-
#
|
7
|
-
# This class handles DELETE/GET/PUT requests for all client/user keys
|
8
|
-
# **except** default public keys, i.e. requests with identity key
|
9
|
-
# "default". Those are handled by ActorDefaultKeyEndpoint. See that class
|
10
|
-
# for more information.
|
11
|
-
#
|
12
|
-
# /users/USER/keys/NAME
|
13
|
-
# /organizations/ORG/clients/CLIENT/keys/NAME
|
14
|
-
class ActorKeyEndpoint < RestBase
|
15
|
-
def get(request)
|
16
|
-
validate_actor!(request)
|
17
|
-
key_path = data_path(request)
|
18
|
-
already_json_response(200, get_data(request, key_path))
|
19
|
-
end
|
20
|
-
|
21
|
-
def delete(request)
|
22
|
-
validate_actor!(request) # 404 if actor doesn't exist
|
23
|
-
|
24
|
-
key_path = data_path(request)
|
25
|
-
data = get_data(request, key_path)
|
26
|
-
delete_data(request, key_path)
|
27
|
-
|
28
|
-
already_json_response(200, data)
|
29
|
-
end
|
30
|
-
|
31
|
-
def put(request)
|
32
|
-
validate_actor!(request) # 404 if actor doesn't exist
|
33
|
-
set_data(request, data_path(request), request.body)
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
# Returns the keys data store path, which is the same as
|
39
|
-
# `request.rest_path` except with "client_keys" instead of "clients" or
|
40
|
-
# "user_keys" instead of "users."
|
41
|
-
def data_path(request)
|
42
|
-
request.rest_path.dup.tap do |path|
|
43
|
-
if client?(request)
|
44
|
-
path[2] = "client_keys"
|
45
|
-
else
|
46
|
-
path[0] = "user_keys"
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# Raises RestErrorResponse (404) if actor doesn't exist
|
52
|
-
def validate_actor!(request)
|
53
|
-
actor_path = request.rest_path[ client?(request) ? 0..3 : 0..1 ]
|
54
|
-
get_data(request, actor_path)
|
55
|
-
end
|
56
|
-
|
57
|
-
def client?(request)
|
58
|
-
request.rest_path[2] == "clients"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
1
|
+
require_relative "../rest_base"
|
2
|
+
|
3
|
+
module ChefZero
|
4
|
+
module Endpoints
|
5
|
+
# ActorKeyEndpoint
|
6
|
+
#
|
7
|
+
# This class handles DELETE/GET/PUT requests for all client/user keys
|
8
|
+
# **except** default public keys, i.e. requests with identity key
|
9
|
+
# "default". Those are handled by ActorDefaultKeyEndpoint. See that class
|
10
|
+
# for more information.
|
11
|
+
#
|
12
|
+
# /users/USER/keys/NAME
|
13
|
+
# /organizations/ORG/clients/CLIENT/keys/NAME
|
14
|
+
class ActorKeyEndpoint < RestBase
|
15
|
+
def get(request)
|
16
|
+
validate_actor!(request)
|
17
|
+
key_path = data_path(request)
|
18
|
+
already_json_response(200, get_data(request, key_path))
|
19
|
+
end
|
20
|
+
|
21
|
+
def delete(request)
|
22
|
+
validate_actor!(request) # 404 if actor doesn't exist
|
23
|
+
|
24
|
+
key_path = data_path(request)
|
25
|
+
data = get_data(request, key_path)
|
26
|
+
delete_data(request, key_path)
|
27
|
+
|
28
|
+
already_json_response(200, data)
|
29
|
+
end
|
30
|
+
|
31
|
+
def put(request)
|
32
|
+
validate_actor!(request) # 404 if actor doesn't exist
|
33
|
+
set_data(request, data_path(request), request.body)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# Returns the keys data store path, which is the same as
|
39
|
+
# `request.rest_path` except with "client_keys" instead of "clients" or
|
40
|
+
# "user_keys" instead of "users."
|
41
|
+
def data_path(request)
|
42
|
+
request.rest_path.dup.tap do |path|
|
43
|
+
if client?(request)
|
44
|
+
path[2] = "client_keys"
|
45
|
+
else
|
46
|
+
path[0] = "user_keys"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Raises RestErrorResponse (404) if actor doesn't exist
|
52
|
+
def validate_actor!(request)
|
53
|
+
actor_path = request.rest_path[ client?(request) ? 0..3 : 0..1 ]
|
54
|
+
get_data(request, actor_path)
|
55
|
+
end
|
56
|
+
|
57
|
+
def client?(request)
|
58
|
+
request.rest_path[2] == "clients"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,129 +1,129 @@
|
|
1
|
-
require_relative "../rest_base"
|
2
|
-
|
3
|
-
module ChefZero
|
4
|
-
module Endpoints
|
5
|
-
# /users/USER/keys
|
6
|
-
# /organizations/ORG/clients/CLIENT/keys
|
7
|
-
class ActorKeysEndpoint < RestBase
|
8
|
-
DEFAULT_PUBLIC_KEY_NAME = "default".freeze
|
9
|
-
DATE_FORMAT = "%FT%TZ".freeze # e.g. 2015-12-24T21:00:00Z
|
10
|
-
|
11
|
-
def get(request, alt_uri_root = nil)
|
12
|
-
path = data_path(request)
|
13
|
-
|
14
|
-
# Get actor or 404 if it doesn't exist
|
15
|
-
actor_json = get_data(request, actor_path(request))
|
16
|
-
|
17
|
-
key_names = list_data_or_else(request, path, [])
|
18
|
-
key_names.unshift(DEFAULT_PUBLIC_KEY_NAME) if actor_has_default_public_key?(actor_json)
|
19
|
-
|
20
|
-
result = key_names.map do |key_name|
|
21
|
-
list_key(request, [ *path, key_name ], alt_uri_root)
|
22
|
-
end
|
23
|
-
|
24
|
-
json_response(200, result)
|
25
|
-
end
|
26
|
-
|
27
|
-
def post(request)
|
28
|
-
request_body = parse_json(request.body)
|
29
|
-
|
30
|
-
# Try loading the client or user so a 404 is returned if it doesn't exist
|
31
|
-
actor_json = get_data(request, actor_path(request))
|
32
|
-
|
33
|
-
generate_keys = request_body["public_key"].nil?
|
34
|
-
|
35
|
-
if generate_keys
|
36
|
-
private_key, public_key = server.gen_key_pair
|
37
|
-
else
|
38
|
-
public_key = request_body["public_key"]
|
39
|
-
end
|
40
|
-
|
41
|
-
key_name = request_body["name"]
|
42
|
-
|
43
|
-
if key_name == DEFAULT_PUBLIC_KEY_NAME
|
44
|
-
store_actor_default_public_key!(request, actor_json, public_key)
|
45
|
-
else
|
46
|
-
store_actor_public_key!(request, key_name, public_key, request_body["expiration_date"])
|
47
|
-
end
|
48
|
-
|
49
|
-
response_body = { "uri" => key_uri(request, key_name) }
|
50
|
-
response_body["private_key"] = private_key if generate_keys
|
51
|
-
|
52
|
-
json_response(201, response_body,
|
53
|
-
headers: { "Location" => response_body["uri"] })
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
def store_actor_public_key!(request, name, public_key, expiration_date)
|
59
|
-
data = to_json(
|
60
|
-
"name" => name,
|
61
|
-
"public_key" => public_key,
|
62
|
-
"expiration_date" => expiration_date
|
63
|
-
)
|
64
|
-
|
65
|
-
create_data(request, data_path(request), name, data, :create_dir)
|
66
|
-
end
|
67
|
-
|
68
|
-
def store_actor_default_public_key!(request, actor_json, public_key)
|
69
|
-
actor_data = parse_json(actor_json)
|
70
|
-
|
71
|
-
if actor_data["public_key"]
|
72
|
-
raise RestErrorResponse.new(409, "Object already exists: #{key_uri(request, DEFAULT_PUBLIC_KEY_NAME)}")
|
73
|
-
end
|
74
|
-
|
75
|
-
actor_data["public_key"] = public_key
|
76
|
-
set_data(request, actor_path(request), to_json(actor_data))
|
77
|
-
end
|
78
|
-
|
79
|
-
# Returns the keys data store path, which is the same as
|
80
|
-
# `request.rest_path` except with "user_keys" instead of "users" or
|
81
|
-
# "client_keys" instead of "clients."
|
82
|
-
def data_path(request)
|
83
|
-
request.rest_path.dup.tap do |path|
|
84
|
-
if client?(request)
|
85
|
-
path[2] = "client_keys"
|
86
|
-
else
|
87
|
-
path[0] = "user_keys"
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def list_key(request, data_path, alt_uri_root = nil)
|
93
|
-
key_name, expiration_date =
|
94
|
-
if data_path[-1] == DEFAULT_PUBLIC_KEY_NAME
|
95
|
-
[ DEFAULT_PUBLIC_KEY_NAME, "infinity" ]
|
96
|
-
else
|
97
|
-
parse_json(get_data(request, data_path))
|
98
|
-
.values_at("name", "expiration_date")
|
99
|
-
end
|
100
|
-
|
101
|
-
expired = expiration_date != "infinity" &&
|
102
|
-
DateTime.now > DateTime.strptime(expiration_date, DATE_FORMAT)
|
103
|
-
|
104
|
-
{ "name" => key_name,
|
105
|
-
"uri" => key_uri(request, key_name, alt_uri_root),
|
106
|
-
"expired" => expired }
|
107
|
-
end
|
108
|
-
|
109
|
-
def client?(request)
|
110
|
-
request.rest_path[2] == "clients"
|
111
|
-
end
|
112
|
-
|
113
|
-
def key_uri(request, key_name, alt_uri_root = nil)
|
114
|
-
uri_root = alt_uri_root.nil? ? request.rest_path : alt_uri_root
|
115
|
-
build_uri(request.base_uri, [ *uri_root, key_name ])
|
116
|
-
end
|
117
|
-
|
118
|
-
def actor_path(request)
|
119
|
-
return request.rest_path[0..3] if client?(request)
|
120
|
-
|
121
|
-
request.rest_path[0..1]
|
122
|
-
end
|
123
|
-
|
124
|
-
def actor_has_default_public_key?(actor_json)
|
125
|
-
!!parse_json(actor_json)["public_key"]
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
1
|
+
require_relative "../rest_base"
|
2
|
+
|
3
|
+
module ChefZero
|
4
|
+
module Endpoints
|
5
|
+
# /users/USER/keys
|
6
|
+
# /organizations/ORG/clients/CLIENT/keys
|
7
|
+
class ActorKeysEndpoint < RestBase
|
8
|
+
DEFAULT_PUBLIC_KEY_NAME = "default".freeze
|
9
|
+
DATE_FORMAT = "%FT%TZ".freeze # e.g. 2015-12-24T21:00:00Z
|
10
|
+
|
11
|
+
def get(request, alt_uri_root = nil)
|
12
|
+
path = data_path(request)
|
13
|
+
|
14
|
+
# Get actor or 404 if it doesn't exist
|
15
|
+
actor_json = get_data(request, actor_path(request))
|
16
|
+
|
17
|
+
key_names = list_data_or_else(request, path, [])
|
18
|
+
key_names.unshift(DEFAULT_PUBLIC_KEY_NAME) if actor_has_default_public_key?(actor_json)
|
19
|
+
|
20
|
+
result = key_names.map do |key_name|
|
21
|
+
list_key(request, [ *path, key_name ], alt_uri_root)
|
22
|
+
end
|
23
|
+
|
24
|
+
json_response(200, result)
|
25
|
+
end
|
26
|
+
|
27
|
+
def post(request)
|
28
|
+
request_body = parse_json(request.body)
|
29
|
+
|
30
|
+
# Try loading the client or user so a 404 is returned if it doesn't exist
|
31
|
+
actor_json = get_data(request, actor_path(request))
|
32
|
+
|
33
|
+
generate_keys = request_body["public_key"].nil?
|
34
|
+
|
35
|
+
if generate_keys
|
36
|
+
private_key, public_key = server.gen_key_pair
|
37
|
+
else
|
38
|
+
public_key = request_body["public_key"]
|
39
|
+
end
|
40
|
+
|
41
|
+
key_name = request_body["name"]
|
42
|
+
|
43
|
+
if key_name == DEFAULT_PUBLIC_KEY_NAME
|
44
|
+
store_actor_default_public_key!(request, actor_json, public_key)
|
45
|
+
else
|
46
|
+
store_actor_public_key!(request, key_name, public_key, request_body["expiration_date"])
|
47
|
+
end
|
48
|
+
|
49
|
+
response_body = { "uri" => key_uri(request, key_name) }
|
50
|
+
response_body["private_key"] = private_key if generate_keys
|
51
|
+
|
52
|
+
json_response(201, response_body,
|
53
|
+
headers: { "Location" => response_body["uri"] })
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def store_actor_public_key!(request, name, public_key, expiration_date)
|
59
|
+
data = to_json(
|
60
|
+
"name" => name,
|
61
|
+
"public_key" => public_key,
|
62
|
+
"expiration_date" => expiration_date
|
63
|
+
)
|
64
|
+
|
65
|
+
create_data(request, data_path(request), name, data, :create_dir)
|
66
|
+
end
|
67
|
+
|
68
|
+
def store_actor_default_public_key!(request, actor_json, public_key)
|
69
|
+
actor_data = parse_json(actor_json)
|
70
|
+
|
71
|
+
if actor_data["public_key"]
|
72
|
+
raise RestErrorResponse.new(409, "Object already exists: #{key_uri(request, DEFAULT_PUBLIC_KEY_NAME)}")
|
73
|
+
end
|
74
|
+
|
75
|
+
actor_data["public_key"] = public_key
|
76
|
+
set_data(request, actor_path(request), to_json(actor_data))
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns the keys data store path, which is the same as
|
80
|
+
# `request.rest_path` except with "user_keys" instead of "users" or
|
81
|
+
# "client_keys" instead of "clients."
|
82
|
+
def data_path(request)
|
83
|
+
request.rest_path.dup.tap do |path|
|
84
|
+
if client?(request)
|
85
|
+
path[2] = "client_keys"
|
86
|
+
else
|
87
|
+
path[0] = "user_keys"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def list_key(request, data_path, alt_uri_root = nil)
|
93
|
+
key_name, expiration_date =
|
94
|
+
if data_path[-1] == DEFAULT_PUBLIC_KEY_NAME
|
95
|
+
[ DEFAULT_PUBLIC_KEY_NAME, "infinity" ]
|
96
|
+
else
|
97
|
+
parse_json(get_data(request, data_path))
|
98
|
+
.values_at("name", "expiration_date")
|
99
|
+
end
|
100
|
+
|
101
|
+
expired = expiration_date != "infinity" &&
|
102
|
+
DateTime.now > DateTime.strptime(expiration_date, DATE_FORMAT)
|
103
|
+
|
104
|
+
{ "name" => key_name,
|
105
|
+
"uri" => key_uri(request, key_name, alt_uri_root),
|
106
|
+
"expired" => expired }
|
107
|
+
end
|
108
|
+
|
109
|
+
def client?(request)
|
110
|
+
request.rest_path[2] == "clients"
|
111
|
+
end
|
112
|
+
|
113
|
+
def key_uri(request, key_name, alt_uri_root = nil)
|
114
|
+
uri_root = alt_uri_root.nil? ? request.rest_path : alt_uri_root
|
115
|
+
build_uri(request.base_uri, [ *uri_root, key_name ])
|
116
|
+
end
|
117
|
+
|
118
|
+
def actor_path(request)
|
119
|
+
return request.rest_path[0..3] if client?(request)
|
120
|
+
|
121
|
+
request.rest_path[0..1]
|
122
|
+
end
|
123
|
+
|
124
|
+
def actor_has_default_public_key?(actor_json)
|
125
|
+
!!parse_json(actor_json)["public_key"]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -1,104 +1,104 @@
|
|
1
|
-
require "ffi_yajl" unless defined?(FFI_Yajl)
|
2
|
-
require_relative "rest_list_endpoint"
|
3
|
-
|
4
|
-
module ChefZero
|
5
|
-
module Endpoints
|
6
|
-
# /users, /organizations/ORG/clients or /organizations/ORG/users
|
7
|
-
class ActorsEndpoint < RestListEndpoint
|
8
|
-
def get(request)
|
9
|
-
response = super(request)
|
10
|
-
|
11
|
-
# apply query filters: if one applies, stop processing rest
|
12
|
-
# (precendence matches chef-server: https://github.com/chef/chef-server/blob/268a0c9/src/oc_erchef/apps/chef_objects/src/chef_user.erl#L554-L559)
|
13
|
-
if (value = request.query_params["external_authentication_uid"])
|
14
|
-
response[2] = filter("external_authentication_uid", value, request, response[2])
|
15
|
-
elsif (value = request.query_params["email"])
|
16
|
-
response[2] = filter("email", value, request, response[2], insensitive: true)
|
17
|
-
end
|
18
|
-
|
19
|
-
if request.query_params["verbose"]
|
20
|
-
results = parse_json(response[2])
|
21
|
-
results.each do |name, url|
|
22
|
-
record = get_data(request, request.rest_path + [ name ], :nil)
|
23
|
-
if record
|
24
|
-
record = parse_json(record)
|
25
|
-
record = ChefData::DataNormalizer.normalize_user(record, name, identity_keys, server.options[:osc_compat])
|
26
|
-
results[name] = record
|
27
|
-
end
|
28
|
-
end
|
29
|
-
response[2] = to_json(results)
|
30
|
-
end
|
31
|
-
response
|
32
|
-
end
|
33
|
-
|
34
|
-
def post(request)
|
35
|
-
# First, find out if the user actually posted a public key. If not, make
|
36
|
-
# one.
|
37
|
-
request_body = parse_json(request.body)
|
38
|
-
public_key = request_body["public_key"]
|
39
|
-
|
40
|
-
skip_key_create = !request.api_v0? && !request_body["create_key"]
|
41
|
-
|
42
|
-
if !public_key && !skip_key_create
|
43
|
-
private_key, public_key = server.gen_key_pair
|
44
|
-
request_body["public_key"] = public_key
|
45
|
-
request.body = to_json(request_body)
|
46
|
-
elsif skip_key_create
|
47
|
-
request_body["public_key"] = nil
|
48
|
-
request.body = to_json(request_body)
|
49
|
-
end
|
50
|
-
|
51
|
-
result = super(request)
|
52
|
-
|
53
|
-
if result[0] == 201
|
54
|
-
# If we generated a key, stuff it in the response.
|
55
|
-
user_data = parse_json(result[2])
|
56
|
-
|
57
|
-
key_data = {}
|
58
|
-
key_data["private_key"] = private_key if private_key
|
59
|
-
key_data["public_key"] = public_key unless request.rest_path[0] == "users"
|
60
|
-
|
61
|
-
response =
|
62
|
-
if request.api_v0?
|
63
|
-
user_data.merge!(key_data)
|
64
|
-
elsif skip_key_create && !public_key
|
65
|
-
user_data
|
66
|
-
else
|
67
|
-
actor_name = request_body["name"] || request_body["username"] || request_body["clientname"]
|
68
|
-
|
69
|
-
relpath_to_default_key = [ actor_name, "keys", "default" ]
|
70
|
-
key_data["uri"] = build_uri(request.base_uri, request.rest_path + relpath_to_default_key)
|
71
|
-
key_data["public_key"] = public_key
|
72
|
-
key_data["name"] = "default"
|
73
|
-
key_data["expiration_date"] = "infinity"
|
74
|
-
user_data["chef_key"] = key_data
|
75
|
-
user_data
|
76
|
-
end
|
77
|
-
|
78
|
-
json_response(201, response)
|
79
|
-
else
|
80
|
-
result
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
private
|
85
|
-
|
86
|
-
def filter(key, value, request, resp, opts = {})
|
87
|
-
results = parse_json(resp)
|
88
|
-
new_results = {}
|
89
|
-
results.each do |name, url|
|
90
|
-
record = get_data(request, request.rest_path + [ name ], :nil)
|
91
|
-
if record
|
92
|
-
record = parse_json(record)
|
93
|
-
new_results[name] = url if record[key] && is_equal(record[key], value, opts[:insensitive])
|
94
|
-
end
|
95
|
-
end
|
96
|
-
to_json(new_results)
|
97
|
-
end
|
98
|
-
|
99
|
-
def is_equal(a, b, ignore_case)
|
100
|
-
ignore_case ? a.casecmp(b) == 0 : a == b
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
1
|
+
require "ffi_yajl" unless defined?(FFI_Yajl)
|
2
|
+
require_relative "rest_list_endpoint"
|
3
|
+
|
4
|
+
module ChefZero
|
5
|
+
module Endpoints
|
6
|
+
# /users, /organizations/ORG/clients or /organizations/ORG/users
|
7
|
+
class ActorsEndpoint < RestListEndpoint
|
8
|
+
def get(request)
|
9
|
+
response = super(request)
|
10
|
+
|
11
|
+
# apply query filters: if one applies, stop processing rest
|
12
|
+
# (precendence matches chef-server: https://github.com/chef/chef-server/blob/268a0c9/src/oc_erchef/apps/chef_objects/src/chef_user.erl#L554-L559)
|
13
|
+
if (value = request.query_params["external_authentication_uid"])
|
14
|
+
response[2] = filter("external_authentication_uid", value, request, response[2])
|
15
|
+
elsif (value = request.query_params["email"])
|
16
|
+
response[2] = filter("email", value, request, response[2], insensitive: true)
|
17
|
+
end
|
18
|
+
|
19
|
+
if request.query_params["verbose"]
|
20
|
+
results = parse_json(response[2])
|
21
|
+
results.each do |name, url|
|
22
|
+
record = get_data(request, request.rest_path + [ name ], :nil)
|
23
|
+
if record
|
24
|
+
record = parse_json(record)
|
25
|
+
record = ChefData::DataNormalizer.normalize_user(record, name, identity_keys, server.options[:osc_compat])
|
26
|
+
results[name] = record
|
27
|
+
end
|
28
|
+
end
|
29
|
+
response[2] = to_json(results)
|
30
|
+
end
|
31
|
+
response
|
32
|
+
end
|
33
|
+
|
34
|
+
def post(request)
|
35
|
+
# First, find out if the user actually posted a public key. If not, make
|
36
|
+
# one.
|
37
|
+
request_body = parse_json(request.body)
|
38
|
+
public_key = request_body["public_key"]
|
39
|
+
|
40
|
+
skip_key_create = !request.api_v0? && !request_body["create_key"]
|
41
|
+
|
42
|
+
if !public_key && !skip_key_create
|
43
|
+
private_key, public_key = server.gen_key_pair
|
44
|
+
request_body["public_key"] = public_key
|
45
|
+
request.body = to_json(request_body)
|
46
|
+
elsif skip_key_create
|
47
|
+
request_body["public_key"] = nil
|
48
|
+
request.body = to_json(request_body)
|
49
|
+
end
|
50
|
+
|
51
|
+
result = super(request)
|
52
|
+
|
53
|
+
if result[0] == 201
|
54
|
+
# If we generated a key, stuff it in the response.
|
55
|
+
user_data = parse_json(result[2])
|
56
|
+
|
57
|
+
key_data = {}
|
58
|
+
key_data["private_key"] = private_key if private_key
|
59
|
+
key_data["public_key"] = public_key unless request.rest_path[0] == "users"
|
60
|
+
|
61
|
+
response =
|
62
|
+
if request.api_v0?
|
63
|
+
user_data.merge!(key_data)
|
64
|
+
elsif skip_key_create && !public_key
|
65
|
+
user_data
|
66
|
+
else
|
67
|
+
actor_name = request_body["name"] || request_body["username"] || request_body["clientname"]
|
68
|
+
|
69
|
+
relpath_to_default_key = [ actor_name, "keys", "default" ]
|
70
|
+
key_data["uri"] = build_uri(request.base_uri, request.rest_path + relpath_to_default_key)
|
71
|
+
key_data["public_key"] = public_key
|
72
|
+
key_data["name"] = "default"
|
73
|
+
key_data["expiration_date"] = "infinity"
|
74
|
+
user_data["chef_key"] = key_data
|
75
|
+
user_data
|
76
|
+
end
|
77
|
+
|
78
|
+
json_response(201, response)
|
79
|
+
else
|
80
|
+
result
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def filter(key, value, request, resp, opts = {})
|
87
|
+
results = parse_json(resp)
|
88
|
+
new_results = {}
|
89
|
+
results.each do |name, url|
|
90
|
+
record = get_data(request, request.rest_path + [ name ], :nil)
|
91
|
+
if record
|
92
|
+
record = parse_json(record)
|
93
|
+
new_results[name] = url if record[key] && is_equal(record[key], value, opts[:insensitive])
|
94
|
+
end
|
95
|
+
end
|
96
|
+
to_json(new_results)
|
97
|
+
end
|
98
|
+
|
99
|
+
def is_equal(a, b, ignore_case)
|
100
|
+
ignore_case ? a.casecmp(b) == 0 : a == b
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -1,32 +1,32 @@
|
|
1
|
-
require "ffi_yajl" unless defined?(FFI_Yajl)
|
2
|
-
require_relative "../rest_base"
|
3
|
-
|
4
|
-
module ChefZero
|
5
|
-
module Endpoints
|
6
|
-
# /authenticate_user
|
7
|
-
class AuthenticateUserEndpoint < RestBase
|
8
|
-
def post(request)
|
9
|
-
request_json = FFI_Yajl::Parser.parse(request.body)
|
10
|
-
name = request_json["username"]
|
11
|
-
password = request_json["password"]
|
12
|
-
begin
|
13
|
-
user = data_store.get(["users", name])
|
14
|
-
rescue ChefZero::DataStore::DataNotFoundError
|
15
|
-
raise RestErrorResponse.new(401, "Bad username or password")
|
16
|
-
end
|
17
|
-
user = FFI_Yajl::Parser.parse(user)
|
18
|
-
user = ChefData::DataNormalizer.normalize_user(user, name, [ "username" ], server.options[:osc_compat])
|
19
|
-
if user["password"] != password
|
20
|
-
raise RestErrorResponse.new(401, "Bad username or password")
|
21
|
-
end
|
22
|
-
|
23
|
-
# Include only particular user data in the response
|
24
|
-
user.keep_if { |key, value| %w{first_name last_name display_name email username}.include?(key) }
|
25
|
-
json_response(200, {
|
26
|
-
"status" => "linked",
|
27
|
-
"user" => user,
|
28
|
-
})
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
1
|
+
require "ffi_yajl" unless defined?(FFI_Yajl)
|
2
|
+
require_relative "../rest_base"
|
3
|
+
|
4
|
+
module ChefZero
|
5
|
+
module Endpoints
|
6
|
+
# /authenticate_user
|
7
|
+
class AuthenticateUserEndpoint < RestBase
|
8
|
+
def post(request)
|
9
|
+
request_json = FFI_Yajl::Parser.parse(request.body)
|
10
|
+
name = request_json["username"]
|
11
|
+
password = request_json["password"]
|
12
|
+
begin
|
13
|
+
user = data_store.get(["users", name])
|
14
|
+
rescue ChefZero::DataStore::DataNotFoundError
|
15
|
+
raise RestErrorResponse.new(401, "Bad username or password")
|
16
|
+
end
|
17
|
+
user = FFI_Yajl::Parser.parse(user)
|
18
|
+
user = ChefData::DataNormalizer.normalize_user(user, name, [ "username" ], server.options[:osc_compat])
|
19
|
+
if user["password"] != password
|
20
|
+
raise RestErrorResponse.new(401, "Bad username or password")
|
21
|
+
end
|
22
|
+
|
23
|
+
# Include only particular user data in the response
|
24
|
+
user.keep_if { |key, value| %w{first_name last_name display_name email username}.include?(key) }
|
25
|
+
json_response(200, {
|
26
|
+
"status" => "linked",
|
27
|
+
"user" => user,
|
28
|
+
})
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|