@@ -64,52 +64,46 @@ handle_post_secret(Req) ->
6464 menelaus_util :assert_is_enterprise (),
6565 assert_is_79 (),
6666 with_validated_secret (
67- fun (ToAdd ) ->
67+ fun (ToAdd , _ ) ->
6868 maybe
6969 {ok , Res } ?= cb_cluster_secrets :add_new_secret (ToAdd ),
7070 Formatted = export_secret (Res ),
7171 ns_audit :set_encryption_secret (Req , Formatted ),
7272 menelaus_util :reply_json (Req , {Formatted }),
7373 ok
7474 end
75- end , #{} , Req ).
75+ end , undefined , Req ).
7676
7777handle_put_secret (IdStr , Req ) ->
7878 menelaus_util :assert_is_enterprise (),
7979 assert_is_79 (),
8080 Id = parse_id (IdStr ),
81- case cb_cluster_secrets :get_secret (Id ) of
82- {ok , CurProps } ->
83- with_validated_secret (
84- fun (Props ) ->
85- maybe
86- IsSecretWritableMFA = {? MODULE , is_writable_remote ,
87- [? HIDE (Req ), node ()]},
88- % % replace_secret will check "old usages" inside txn
89- {ok , Res } ?= cb_cluster_secrets :replace_secret (
90- Id , Props , IsSecretWritableMFA ),
91- Formatted = export_secret (Res ),
92- ns_audit :set_encryption_secret (Req , Formatted ),
93- menelaus_util :reply_json (Req , {Formatted }),
94- ok
95- end
96- end , CurProps , Req );
97- {error , not_found } ->
98- % % We don't want PUT to create secrets because we generate id's
99- menelaus_util :reply_not_found (Req )
100- end .
81+ with_validated_secret (
82+ fun (Props , _ ) ->
83+ maybe
84+ IsSecretWritableMFA = {? MODULE , is_writable_remote ,
85+ [? HIDE (Req ), node ()]},
86+ % % replace_secret will check "old usages" inside txn
87+ {ok , Res } ?= cb_cluster_secrets :replace_secret (
88+ Id , Props , IsSecretWritableMFA ),
89+ Formatted = export_secret (Res ),
90+ ns_audit :set_encryption_secret (Req , Formatted ),
91+ menelaus_util :reply_json (Req , {Formatted }),
92+ ok
93+ end
94+ end , Id , Req ).
10195
10296handle_test_post_secret (Req ) ->
10397 menelaus_util :assert_is_enterprise (),
10498 assert_is_79 (),
10599 with_validated_secret (
106- fun (Params ) ->
100+ fun (Params , _ ) ->
107101 maybe
108102 ok ?= cb_cluster_secrets :test (Params , undefined ),
109103 menelaus_util :reply (Req , 200 ),
110104 ok
111105 end
112- end , #{} , Req ).
106+ end , undefined , Req ).
113107
114108handle_test_post_secret (IdStr , Req ) ->
115109 menelaus_util :assert_is_enterprise (),
@@ -140,21 +134,16 @@ handle_test_put_secret(IdStr, Req) ->
140134 menelaus_util :assert_is_enterprise (),
141135 assert_is_79 (),
142136 Id = parse_id (IdStr ),
143- case cb_cluster_secrets :get_secret (Id ) of
144- {ok , CurProps } ->
145- with_validated_secret (
146- fun (Params ) ->
147- maybe
148- ok ?= cb_cluster_secrets :test (Params , CurProps ),
149- menelaus_util :reply (Req , 200 ),
150- ok
151- end
152- end , CurProps , Req );
153- {error , not_found } ->
154- menelaus_util :reply_not_found (Req )
155- end .
156-
157- with_validated_secret (Fun , CurProps , Req ) ->
137+ with_validated_secret (
138+ fun (Params , CurProps ) ->
139+ maybe
140+ ok ?= cb_cluster_secrets :test (Params , CurProps ),
141+ menelaus_util :reply (Req , 200 ),
142+ ok
143+ end
144+ end , Id , Req ).
145+
146+ with_validated_secret (Fun , ExistingId , Req ) ->
158147 % % We need to fetch snapshot with read_consistency in order to deal with
159148 % % the following scenario:
160149 % % 1. User creates a bucket on a node which is not an orchestrator
@@ -167,28 +156,42 @@ with_validated_secret(Fun, CurProps, Req) ->
167156 % [ns_bucket:fetch_snapshot(all, _, [uuid])],
168157 [cb_cluster_secrets :fetch_snapshot_in_txn (_ )],
169158 #{read_consistency => quorum }),
170- validator :handle (
171- fun (RawProps ) ->
172- maybe
173- Props = import_secret (RawProps ),
174- % % Note: All "usages" should be writable by current user.
175- % % This includes "new usages" (usages that are being set)
176- % % and "old usages" (usages that are being replaced)
177- % % Checking "new usages" here:
178- true ?= is_writable (Props , Req ),
179- % % Fun is responsible for checking "old usages" inside txn
180- ok ?= Fun (Props )
181- else
182- false ->
183- menelaus_util :web_exception (403 , format_error (forbidden ));
184- {error , forbidden } ->
185- menelaus_util :web_exception (403 , format_error (forbidden ));
186- {error , no_quorum } ->
187- menelaus_util :web_exception (503 , format_error (no_quorum ));
188- {error , Reason } ->
189- menelaus_util :reply_global_error (Req , format_error (Reason ))
190- end
191- end , Req , json , secret_validators (CurProps , Snapshot )).
159+ CurPropsRes = case ExistingId of
160+ undefined -> {ok , #{}};
161+ _ -> cb_cluster_secrets :get_secret (ExistingId , Snapshot )
162+ end ,
163+
164+ case CurPropsRes of
165+ {ok , CurProps } ->
166+ validator :handle (
167+ fun (RawProps ) ->
168+ maybe
169+ Props = import_secret (RawProps ),
170+ % % Note: All "usages" should be writable by current user.
171+ % % This includes "new usages" (usages that are being set)
172+ % % and "old usages" (usages that are being replaced)
173+ % % Checking "new usages" here:
174+ true ?= is_writable (Props , Req ),
175+ % % Fun is responsible for checking "old usages" inside txn
176+ ok ?= Fun (Props , CurProps )
177+ else
178+ false ->
179+ menelaus_util :web_exception (403 ,
180+ format_error (forbidden ));
181+ {error , forbidden } ->
182+ menelaus_util :web_exception (403 ,
183+ format_error (forbidden ));
184+ {error , no_quorum } ->
185+ menelaus_util :web_exception (503 ,
186+ format_error (no_quorum ));
187+ {error , Reason } ->
188+ menelaus_util :reply_global_error (Req ,
189+ format_error (Reason ))
190+ end
191+ end , Req , json , secret_validators (CurProps , Snapshot ));
192+ {error , not_found } ->
193+ menelaus_util :reply_not_found (Req )
194+ end .
192195
193196% % Note: CurProps can only be used for static fields validation here.
194197% % Any field that can be modified and needs to use CurProps should be
0 commit comments