]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include "common/ceph_json.h" | |
5 | ||
6 | #include "rgw_op.h" | |
7 | #include "rgw_user.h" | |
8 | #include "rgw_rest_user.h" | |
9 | ||
10 | #include "include/str_list.h" | |
11 | #include "include/assert.h" | |
12 | ||
13 | #define dout_subsys ceph_subsys_rgw | |
14 | ||
15 | class RGWOp_User_Info : public RGWRESTOp { | |
16 | ||
17 | public: | |
18 | RGWOp_User_Info() {} | |
19 | ||
20 | int check_caps(RGWUserCaps& caps) override { | |
21 | return caps.check_cap("users", RGW_CAP_READ); | |
22 | } | |
23 | ||
24 | void execute() override; | |
25 | ||
26 | const string name() override { return "get_user_info"; } | |
27 | }; | |
28 | ||
29 | void RGWOp_User_Info::execute() | |
30 | { | |
31 | RGWUserAdminOpState op_state; | |
32 | ||
33 | std::string uid_str; | |
34 | bool fetch_stats; | |
3efd9988 | 35 | bool sync_stats; |
7c673cae FG |
36 | |
37 | RESTArgs::get_string(s, "uid", uid_str, &uid_str); | |
38 | ||
39 | // if uid was not supplied in rest argument, error out now, otherwise we'll | |
40 | // end up initializing anonymous user, for which keys.init will eventually | |
41 | // return -EACESS | |
42 | if (uid_str.empty()){ | |
43 | http_ret=-EINVAL; | |
44 | return; | |
45 | } | |
46 | ||
47 | rgw_user uid(uid_str); | |
48 | ||
49 | RESTArgs::get_bool(s, "stats", false, &fetch_stats); | |
50 | ||
3efd9988 FG |
51 | RESTArgs::get_bool(s, "sync", false, &sync_stats); |
52 | ||
7c673cae FG |
53 | op_state.set_user_id(uid); |
54 | op_state.set_fetch_stats(fetch_stats); | |
3efd9988 | 55 | op_state.set_sync_stats(sync_stats); |
7c673cae FG |
56 | |
57 | http_ret = RGWUserAdminOp_User::info(store, op_state, flusher); | |
58 | } | |
59 | ||
60 | class RGWOp_User_Create : public RGWRESTOp { | |
61 | ||
62 | public: | |
63 | RGWOp_User_Create() {} | |
64 | ||
65 | int check_caps(RGWUserCaps& caps) override { | |
66 | return caps.check_cap("users", RGW_CAP_WRITE); | |
67 | } | |
68 | ||
69 | void execute() override; | |
70 | ||
71 | const string name() override { return "create_user"; } | |
72 | }; | |
73 | ||
74 | void RGWOp_User_Create::execute() | |
75 | { | |
76 | std::string uid_str; | |
77 | std::string display_name; | |
78 | std::string email; | |
79 | std::string access_key; | |
80 | std::string secret_key; | |
81 | std::string key_type_str; | |
82 | std::string caps; | |
d2e6a577 | 83 | std::string tenant_name; |
7c673cae FG |
84 | |
85 | bool gen_key; | |
86 | bool suspended; | |
87 | bool system; | |
88 | bool exclusive; | |
89 | ||
90 | int32_t max_buckets; | |
91 | int32_t default_max_buckets = s->cct->_conf->rgw_user_max_buckets; | |
92 | ||
93 | RGWUserAdminOpState op_state; | |
94 | ||
95 | RESTArgs::get_string(s, "uid", uid_str, &uid_str); | |
96 | rgw_user uid(uid_str); | |
97 | ||
98 | RESTArgs::get_string(s, "display-name", display_name, &display_name); | |
99 | RESTArgs::get_string(s, "email", email, &email); | |
100 | RESTArgs::get_string(s, "access-key", access_key, &access_key); | |
101 | RESTArgs::get_string(s, "secret-key", secret_key, &secret_key); | |
102 | RESTArgs::get_string(s, "key-type", key_type_str, &key_type_str); | |
103 | RESTArgs::get_string(s, "user-caps", caps, &caps); | |
d2e6a577 | 104 | RESTArgs::get_string(s, "tenant", tenant_name, &tenant_name); |
7c673cae FG |
105 | RESTArgs::get_bool(s, "generate-key", true, &gen_key); |
106 | RESTArgs::get_bool(s, "suspended", false, &suspended); | |
107 | RESTArgs::get_int32(s, "max-buckets", default_max_buckets, &max_buckets); | |
108 | RESTArgs::get_bool(s, "system", false, &system); | |
109 | RESTArgs::get_bool(s, "exclusive", false, &exclusive); | |
110 | ||
111 | if (!s->user->system && system) { | |
112 | ldout(s->cct, 0) << "cannot set system flag by non-system user" << dendl; | |
113 | http_ret = -EINVAL; | |
114 | return; | |
115 | } | |
116 | ||
d2e6a577 FG |
117 | if (!tenant_name.empty()) { |
118 | uid.tenant = tenant_name; | |
119 | } | |
120 | ||
7c673cae FG |
121 | // TODO: validate required args are passed in. (for eg. uid and display_name here) |
122 | op_state.set_user_id(uid); | |
123 | op_state.set_display_name(display_name); | |
124 | op_state.set_user_email(email); | |
125 | op_state.set_caps(caps); | |
126 | op_state.set_access_key(access_key); | |
127 | op_state.set_secret_key(secret_key); | |
128 | ||
129 | if (!key_type_str.empty()) { | |
130 | int32_t key_type = KEY_TYPE_UNDEFINED; | |
131 | if (key_type_str.compare("swift") == 0) | |
132 | key_type = KEY_TYPE_SWIFT; | |
133 | else if (key_type_str.compare("s3") == 0) | |
134 | key_type = KEY_TYPE_S3; | |
135 | ||
136 | op_state.set_key_type(key_type); | |
137 | } | |
138 | ||
139 | if (max_buckets != default_max_buckets) | |
140 | op_state.set_max_buckets(max_buckets); | |
141 | ||
142 | if (s->info.args.exists("suspended")) | |
143 | op_state.set_suspension(suspended); | |
144 | ||
145 | if (s->info.args.exists("system")) | |
146 | op_state.set_system(system); | |
147 | ||
148 | if (s->info.args.exists("exclusive")) | |
149 | op_state.set_exclusive(exclusive); | |
150 | ||
151 | if (gen_key) | |
152 | op_state.set_generate_key(); | |
153 | ||
154 | RGWQuotaInfo bucket_quota; | |
155 | RGWQuotaInfo user_quota; | |
156 | ||
157 | if (s->cct->_conf->rgw_bucket_default_quota_max_objects >= 0) { | |
158 | bucket_quota.max_objects = s->cct->_conf->rgw_bucket_default_quota_max_objects; | |
159 | bucket_quota.enabled = true; | |
160 | } | |
161 | ||
162 | if (s->cct->_conf->rgw_bucket_default_quota_max_size >= 0) { | |
163 | bucket_quota.max_size = s->cct->_conf->rgw_bucket_default_quota_max_size; | |
164 | bucket_quota.enabled = true; | |
165 | } | |
166 | ||
167 | if (s->cct->_conf->rgw_user_default_quota_max_objects >= 0) { | |
168 | user_quota.max_objects = s->cct->_conf->rgw_user_default_quota_max_objects; | |
169 | user_quota.enabled = true; | |
170 | } | |
171 | ||
172 | if (s->cct->_conf->rgw_user_default_quota_max_size >= 0) { | |
173 | user_quota.max_size = s->cct->_conf->rgw_user_default_quota_max_size; | |
174 | user_quota.enabled = true; | |
175 | } | |
176 | ||
177 | if (bucket_quota.enabled) { | |
178 | op_state.set_bucket_quota(bucket_quota); | |
179 | } | |
180 | ||
181 | if (user_quota.enabled) { | |
182 | op_state.set_user_quota(user_quota); | |
183 | } | |
184 | ||
185 | http_ret = RGWUserAdminOp_User::create(store, op_state, flusher); | |
186 | } | |
187 | ||
188 | class RGWOp_User_Modify : public RGWRESTOp { | |
189 | ||
190 | public: | |
191 | RGWOp_User_Modify() {} | |
192 | ||
193 | int check_caps(RGWUserCaps& caps) override { | |
194 | return caps.check_cap("users", RGW_CAP_WRITE); | |
195 | } | |
196 | ||
197 | void execute() override; | |
198 | ||
199 | const string name() override { return "modify_user"; } | |
200 | }; | |
201 | ||
202 | void RGWOp_User_Modify::execute() | |
203 | { | |
204 | std::string uid_str; | |
205 | std::string display_name; | |
206 | std::string email; | |
207 | std::string access_key; | |
208 | std::string secret_key; | |
209 | std::string key_type_str; | |
210 | std::string caps; | |
211 | ||
212 | bool gen_key; | |
213 | bool suspended; | |
214 | bool system; | |
28e407b8 | 215 | bool email_set; |
94b18763 | 216 | bool quota_set; |
7c673cae FG |
217 | int32_t max_buckets; |
218 | ||
219 | RGWUserAdminOpState op_state; | |
220 | ||
221 | RESTArgs::get_string(s, "uid", uid_str, &uid_str); | |
222 | rgw_user uid(uid_str); | |
223 | ||
224 | RESTArgs::get_string(s, "display-name", display_name, &display_name); | |
28e407b8 | 225 | RESTArgs::get_string(s, "email", email, &email, &email_set); |
7c673cae FG |
226 | RESTArgs::get_string(s, "access-key", access_key, &access_key); |
227 | RESTArgs::get_string(s, "secret-key", secret_key, &secret_key); | |
228 | RESTArgs::get_string(s, "user-caps", caps, &caps); | |
229 | RESTArgs::get_bool(s, "generate-key", false, &gen_key); | |
230 | RESTArgs::get_bool(s, "suspended", false, &suspended); | |
94b18763 | 231 | RESTArgs::get_int32(s, "max-buckets", RGW_DEFAULT_MAX_BUCKETS, &max_buckets, "a_set); |
7c673cae FG |
232 | RESTArgs::get_string(s, "key-type", key_type_str, &key_type_str); |
233 | ||
234 | RESTArgs::get_bool(s, "system", false, &system); | |
235 | ||
236 | if (!s->user->system && system) { | |
237 | ldout(s->cct, 0) << "cannot set system flag by non-system user" << dendl; | |
238 | http_ret = -EINVAL; | |
239 | return; | |
240 | } | |
241 | ||
242 | op_state.set_user_id(uid); | |
243 | op_state.set_display_name(display_name); | |
28e407b8 AA |
244 | |
245 | if (email_set) | |
246 | op_state.set_user_email(email); | |
247 | ||
7c673cae FG |
248 | op_state.set_caps(caps); |
249 | op_state.set_access_key(access_key); | |
250 | op_state.set_secret_key(secret_key); | |
251 | ||
94b18763 | 252 | if (quota_set) |
7c673cae FG |
253 | op_state.set_max_buckets(max_buckets); |
254 | ||
255 | if (gen_key) | |
256 | op_state.set_generate_key(); | |
257 | ||
258 | if (!key_type_str.empty()) { | |
259 | int32_t key_type = KEY_TYPE_UNDEFINED; | |
260 | if (key_type_str.compare("swift") == 0) | |
261 | key_type = KEY_TYPE_SWIFT; | |
262 | else if (key_type_str.compare("s3") == 0) | |
263 | key_type = KEY_TYPE_S3; | |
264 | ||
265 | op_state.set_key_type(key_type); | |
266 | } | |
267 | ||
268 | if (s->info.args.exists("suspended")) | |
269 | op_state.set_suspension(suspended); | |
270 | ||
271 | if (s->info.args.exists("system")) | |
272 | op_state.set_system(system); | |
273 | ||
274 | http_ret = RGWUserAdminOp_User::modify(store, op_state, flusher); | |
275 | } | |
276 | ||
277 | class RGWOp_User_Remove : public RGWRESTOp { | |
278 | ||
279 | public: | |
280 | RGWOp_User_Remove() {} | |
281 | ||
282 | int check_caps(RGWUserCaps& caps) override { | |
283 | return caps.check_cap("users", RGW_CAP_WRITE); | |
284 | } | |
285 | ||
286 | void execute() override; | |
287 | ||
288 | const string name() override { return "remove_user"; } | |
289 | }; | |
290 | ||
291 | void RGWOp_User_Remove::execute() | |
292 | { | |
293 | std::string uid_str; | |
294 | bool purge_data; | |
295 | ||
296 | RGWUserAdminOpState op_state; | |
297 | ||
298 | RESTArgs::get_string(s, "uid", uid_str, &uid_str); | |
299 | rgw_user uid(uid_str); | |
300 | ||
301 | RESTArgs::get_bool(s, "purge-data", false, &purge_data); | |
302 | ||
303 | // FIXME: no double checking | |
304 | if (!uid.empty()) | |
305 | op_state.set_user_id(uid); | |
306 | ||
307 | op_state.set_purge_data(purge_data); | |
308 | ||
309 | http_ret = RGWUserAdminOp_User::remove(store, op_state, flusher); | |
310 | } | |
311 | ||
312 | class RGWOp_Subuser_Create : public RGWRESTOp { | |
313 | ||
314 | public: | |
315 | RGWOp_Subuser_Create() {} | |
316 | ||
317 | int check_caps(RGWUserCaps& caps) override { | |
318 | return caps.check_cap("users", RGW_CAP_WRITE); | |
319 | } | |
320 | ||
321 | void execute() override; | |
322 | ||
323 | const string name() override { return "create_subuser"; } | |
324 | }; | |
325 | ||
326 | void RGWOp_Subuser_Create::execute() | |
327 | { | |
328 | std::string uid_str; | |
329 | std::string subuser; | |
330 | std::string secret_key; | |
331 | std::string access_key; | |
332 | std::string perm_str; | |
333 | std::string key_type_str; | |
334 | ||
335 | bool gen_subuser = false; // FIXME placeholder | |
336 | bool gen_secret; | |
337 | bool gen_access; | |
338 | ||
339 | uint32_t perm_mask = 0; | |
340 | int32_t key_type = KEY_TYPE_SWIFT; | |
341 | ||
342 | RGWUserAdminOpState op_state; | |
343 | ||
344 | RESTArgs::get_string(s, "uid", uid_str, &uid_str); | |
345 | rgw_user uid(uid_str); | |
346 | ||
347 | RESTArgs::get_string(s, "subuser", subuser, &subuser); | |
348 | RESTArgs::get_string(s, "access-key", access_key, &access_key); | |
349 | RESTArgs::get_string(s, "secret-key", secret_key, &secret_key); | |
350 | RESTArgs::get_string(s, "access", perm_str, &perm_str); | |
351 | RESTArgs::get_string(s, "key-type", key_type_str, &key_type_str); | |
352 | //RESTArgs::get_bool(s, "generate-subuser", false, &gen_subuser); | |
353 | RESTArgs::get_bool(s, "generate-secret", false, &gen_secret); | |
354 | RESTArgs::get_bool(s, "gen-access-key", false, &gen_access); | |
355 | ||
356 | perm_mask = rgw_str_to_perm(perm_str.c_str()); | |
357 | op_state.set_perm(perm_mask); | |
358 | ||
359 | op_state.set_user_id(uid); | |
360 | op_state.set_subuser(subuser); | |
361 | op_state.set_access_key(access_key); | |
362 | op_state.set_secret_key(secret_key); | |
363 | op_state.set_generate_subuser(gen_subuser); | |
364 | ||
365 | if (gen_access) | |
366 | op_state.set_gen_access(); | |
367 | ||
368 | if (gen_secret) | |
369 | op_state.set_gen_secret(); | |
370 | ||
371 | if (!key_type_str.empty()) { | |
372 | if (key_type_str.compare("swift") == 0) | |
373 | key_type = KEY_TYPE_SWIFT; | |
374 | else if (key_type_str.compare("s3") == 0) | |
375 | key_type = KEY_TYPE_S3; | |
376 | } | |
377 | op_state.set_key_type(key_type); | |
378 | ||
379 | http_ret = RGWUserAdminOp_Subuser::create(store, op_state, flusher); | |
380 | } | |
381 | ||
382 | class RGWOp_Subuser_Modify : public RGWRESTOp { | |
383 | ||
384 | public: | |
385 | RGWOp_Subuser_Modify() {} | |
386 | ||
387 | int check_caps(RGWUserCaps& caps) override { | |
388 | return caps.check_cap("users", RGW_CAP_WRITE); | |
389 | } | |
390 | ||
391 | void execute() override; | |
392 | ||
393 | const string name() override { return "modify_subuser"; } | |
394 | }; | |
395 | ||
396 | void RGWOp_Subuser_Modify::execute() | |
397 | { | |
398 | std::string uid_str; | |
399 | std::string subuser; | |
400 | std::string secret_key; | |
401 | std::string key_type_str; | |
402 | std::string perm_str; | |
403 | ||
404 | RGWUserAdminOpState op_state; | |
405 | ||
406 | uint32_t perm_mask; | |
407 | int32_t key_type = KEY_TYPE_SWIFT; | |
408 | ||
409 | bool gen_secret; | |
410 | ||
411 | RESTArgs::get_string(s, "uid", uid_str, &uid_str); | |
412 | rgw_user uid(uid_str); | |
413 | ||
414 | RESTArgs::get_string(s, "subuser", subuser, &subuser); | |
415 | RESTArgs::get_string(s, "secret-key", secret_key, &secret_key); | |
416 | RESTArgs::get_string(s, "access", perm_str, &perm_str); | |
417 | RESTArgs::get_string(s, "key-type", key_type_str, &key_type_str); | |
418 | RESTArgs::get_bool(s, "generate-secret", false, &gen_secret); | |
419 | ||
420 | perm_mask = rgw_str_to_perm(perm_str.c_str()); | |
421 | op_state.set_perm(perm_mask); | |
422 | ||
423 | op_state.set_user_id(uid); | |
424 | op_state.set_subuser(subuser); | |
b32b8144 FG |
425 | |
426 | if (!secret_key.empty()) | |
427 | op_state.set_secret_key(secret_key); | |
428 | ||
429 | if (gen_secret) | |
430 | op_state.set_gen_secret(); | |
7c673cae FG |
431 | |
432 | if (!key_type_str.empty()) { | |
433 | if (key_type_str.compare("swift") == 0) | |
434 | key_type = KEY_TYPE_SWIFT; | |
435 | else if (key_type_str.compare("s3") == 0) | |
436 | key_type = KEY_TYPE_S3; | |
437 | } | |
438 | op_state.set_key_type(key_type); | |
439 | ||
440 | http_ret = RGWUserAdminOp_Subuser::modify(store, op_state, flusher); | |
441 | } | |
442 | ||
443 | class RGWOp_Subuser_Remove : public RGWRESTOp { | |
444 | ||
445 | public: | |
446 | RGWOp_Subuser_Remove() {} | |
447 | ||
448 | int check_caps(RGWUserCaps& caps) override { | |
449 | return caps.check_cap("users", RGW_CAP_WRITE); | |
450 | } | |
451 | ||
452 | void execute() override; | |
453 | ||
454 | const string name() override { return "remove_subuser"; } | |
455 | }; | |
456 | ||
457 | void RGWOp_Subuser_Remove::execute() | |
458 | { | |
459 | std::string uid_str; | |
460 | std::string subuser; | |
461 | bool purge_keys; | |
462 | ||
463 | RGWUserAdminOpState op_state; | |
464 | ||
465 | RESTArgs::get_string(s, "uid", uid_str, &uid_str); | |
466 | rgw_user uid(uid_str); | |
467 | ||
468 | RESTArgs::get_string(s, "subuser", subuser, &subuser); | |
469 | RESTArgs::get_bool(s, "purge-keys", true, &purge_keys); | |
470 | ||
471 | op_state.set_user_id(uid); | |
472 | op_state.set_subuser(subuser); | |
473 | ||
474 | if (purge_keys) | |
475 | op_state.set_purge_keys(); | |
476 | ||
477 | http_ret = RGWUserAdminOp_Subuser::remove(store, op_state, flusher); | |
478 | } | |
479 | ||
480 | class RGWOp_Key_Create : public RGWRESTOp { | |
481 | ||
482 | public: | |
483 | RGWOp_Key_Create() {} | |
484 | ||
485 | int check_caps(RGWUserCaps& caps) override { | |
486 | return caps.check_cap("users", RGW_CAP_WRITE); | |
487 | } | |
488 | ||
489 | void execute() override; | |
490 | ||
491 | const string name() override { return "create_access_key"; } | |
492 | }; | |
493 | ||
494 | void RGWOp_Key_Create::execute() | |
495 | { | |
496 | std::string uid_str; | |
497 | std::string subuser; | |
498 | std::string access_key; | |
499 | std::string secret_key; | |
500 | std::string key_type_str; | |
501 | ||
502 | bool gen_key; | |
503 | ||
504 | RGWUserAdminOpState op_state; | |
505 | ||
506 | RESTArgs::get_string(s, "uid", uid_str, &uid_str); | |
507 | rgw_user uid(uid_str); | |
508 | ||
509 | RESTArgs::get_string(s, "subuser", subuser, &subuser); | |
510 | RESTArgs::get_string(s, "access-key", access_key, &access_key); | |
511 | RESTArgs::get_string(s, "secret-key", secret_key, &secret_key); | |
512 | RESTArgs::get_string(s, "key-type", key_type_str, &key_type_str); | |
513 | RESTArgs::get_bool(s, "generate-key", true, &gen_key); | |
514 | ||
515 | op_state.set_user_id(uid); | |
516 | op_state.set_subuser(subuser); | |
517 | op_state.set_access_key(access_key); | |
518 | op_state.set_secret_key(secret_key); | |
519 | ||
520 | if (gen_key) | |
521 | op_state.set_generate_key(); | |
522 | ||
523 | if (!key_type_str.empty()) { | |
524 | int32_t key_type = KEY_TYPE_UNDEFINED; | |
525 | if (key_type_str.compare("swift") == 0) | |
526 | key_type = KEY_TYPE_SWIFT; | |
527 | else if (key_type_str.compare("s3") == 0) | |
528 | key_type = KEY_TYPE_S3; | |
529 | ||
530 | op_state.set_key_type(key_type); | |
531 | } | |
532 | ||
533 | http_ret = RGWUserAdminOp_Key::create(store, op_state, flusher); | |
534 | } | |
535 | ||
536 | class RGWOp_Key_Remove : public RGWRESTOp { | |
537 | ||
538 | public: | |
539 | RGWOp_Key_Remove() {} | |
540 | ||
541 | int check_caps(RGWUserCaps& caps) override { | |
542 | return caps.check_cap("users", RGW_CAP_WRITE); | |
543 | } | |
544 | ||
545 | void execute() override; | |
546 | ||
547 | const string name() override { return "remove_access_key"; } | |
548 | }; | |
549 | ||
550 | void RGWOp_Key_Remove::execute() | |
551 | { | |
552 | std::string uid_str; | |
553 | std::string subuser; | |
554 | std::string access_key; | |
555 | std::string key_type_str; | |
556 | ||
557 | RGWUserAdminOpState op_state; | |
558 | ||
559 | RESTArgs::get_string(s, "uid", uid_str, &uid_str); | |
560 | rgw_user uid(uid_str); | |
561 | ||
562 | RESTArgs::get_string(s, "subuser", subuser, &subuser); | |
563 | RESTArgs::get_string(s, "access-key", access_key, &access_key); | |
564 | RESTArgs::get_string(s, "key-type", key_type_str, &key_type_str); | |
565 | ||
566 | op_state.set_user_id(uid); | |
567 | op_state.set_subuser(subuser); | |
568 | op_state.set_access_key(access_key); | |
569 | ||
570 | if (!key_type_str.empty()) { | |
571 | int32_t key_type = KEY_TYPE_UNDEFINED; | |
572 | if (key_type_str.compare("swift") == 0) | |
573 | key_type = KEY_TYPE_SWIFT; | |
574 | else if (key_type_str.compare("s3") == 0) | |
575 | key_type = KEY_TYPE_S3; | |
576 | ||
577 | op_state.set_key_type(key_type); | |
578 | } | |
579 | ||
580 | http_ret = RGWUserAdminOp_Key::remove(store, op_state, flusher); | |
581 | } | |
582 | ||
583 | class RGWOp_Caps_Add : public RGWRESTOp { | |
584 | ||
585 | public: | |
586 | RGWOp_Caps_Add() {} | |
587 | ||
588 | int check_caps(RGWUserCaps& caps) override { | |
589 | return caps.check_cap("users", RGW_CAP_WRITE); | |
590 | } | |
591 | ||
592 | void execute() override; | |
593 | ||
594 | const string name() override { return "add_user_caps"; } | |
595 | }; | |
596 | ||
597 | void RGWOp_Caps_Add::execute() | |
598 | { | |
599 | std::string uid_str; | |
600 | std::string caps; | |
601 | ||
602 | RGWUserAdminOpState op_state; | |
603 | ||
604 | RESTArgs::get_string(s, "uid", uid_str, &uid_str); | |
605 | rgw_user uid(uid_str); | |
606 | ||
607 | RESTArgs::get_string(s, "user-caps", caps, &caps); | |
608 | ||
609 | op_state.set_user_id(uid); | |
610 | op_state.set_caps(caps); | |
611 | ||
612 | http_ret = RGWUserAdminOp_Caps::add(store, op_state, flusher); | |
613 | } | |
614 | ||
615 | class RGWOp_Caps_Remove : public RGWRESTOp { | |
616 | ||
617 | public: | |
618 | RGWOp_Caps_Remove() {} | |
619 | ||
620 | int check_caps(RGWUserCaps& caps) override { | |
621 | return caps.check_cap("users", RGW_CAP_WRITE); | |
622 | } | |
623 | ||
624 | void execute() override; | |
625 | ||
626 | const string name() override { return "remove_user_caps"; } | |
627 | }; | |
628 | ||
629 | void RGWOp_Caps_Remove::execute() | |
630 | { | |
631 | std::string uid_str; | |
632 | std::string caps; | |
633 | ||
634 | RGWUserAdminOpState op_state; | |
635 | ||
636 | RESTArgs::get_string(s, "uid", uid_str, &uid_str); | |
637 | rgw_user uid(uid_str); | |
638 | ||
639 | RESTArgs::get_string(s, "user-caps", caps, &caps); | |
640 | ||
641 | op_state.set_user_id(uid); | |
642 | op_state.set_caps(caps); | |
643 | ||
644 | http_ret = RGWUserAdminOp_Caps::remove(store, op_state, flusher); | |
645 | } | |
646 | ||
647 | struct UserQuotas { | |
648 | RGWQuotaInfo bucket_quota; | |
649 | RGWQuotaInfo user_quota; | |
650 | ||
651 | UserQuotas() {} | |
652 | ||
653 | explicit UserQuotas(RGWUserInfo& info) : bucket_quota(info.bucket_quota), | |
654 | user_quota(info.user_quota) {} | |
655 | ||
656 | void dump(Formatter *f) const { | |
657 | encode_json("bucket_quota", bucket_quota, f); | |
658 | encode_json("user_quota", user_quota, f); | |
659 | } | |
660 | void decode_json(JSONObj *obj) { | |
661 | JSONDecoder::decode_json("bucket_quota", bucket_quota, obj); | |
662 | JSONDecoder::decode_json("user_quota", user_quota, obj); | |
663 | } | |
664 | }; | |
665 | ||
666 | class RGWOp_Quota_Info : public RGWRESTOp { | |
667 | ||
668 | public: | |
669 | RGWOp_Quota_Info() {} | |
670 | ||
671 | int check_caps(RGWUserCaps& caps) override { | |
672 | return caps.check_cap("users", RGW_CAP_READ); | |
673 | } | |
674 | ||
675 | void execute() override; | |
676 | ||
677 | const string name() override { return "get_quota_info"; } | |
678 | }; | |
679 | ||
680 | ||
681 | void RGWOp_Quota_Info::execute() | |
682 | { | |
683 | RGWUserAdminOpState op_state; | |
684 | ||
685 | std::string uid_str; | |
686 | std::string quota_type; | |
687 | ||
688 | RESTArgs::get_string(s, "uid", uid_str, &uid_str); | |
689 | RESTArgs::get_string(s, "quota-type", quota_type, "a_type); | |
690 | ||
691 | if (uid_str.empty()) { | |
692 | http_ret = -EINVAL; | |
693 | return; | |
694 | } | |
695 | ||
696 | rgw_user uid(uid_str); | |
697 | ||
698 | bool show_all = quota_type.empty(); | |
699 | bool show_bucket = show_all || (quota_type == "bucket"); | |
700 | bool show_user = show_all || (quota_type == "user"); | |
701 | ||
702 | if (!(show_all || show_bucket || show_user)) { | |
703 | http_ret = -EINVAL; | |
704 | return; | |
705 | } | |
706 | ||
707 | op_state.set_user_id(uid); | |
708 | ||
709 | RGWUser user; | |
710 | http_ret = user.init(store, op_state); | |
711 | if (http_ret < 0) | |
712 | return; | |
713 | ||
224ce89b WB |
714 | if (!op_state.has_existing_user()) { |
715 | http_ret = -ERR_NO_SUCH_USER; | |
716 | return; | |
717 | } | |
718 | ||
7c673cae FG |
719 | RGWUserInfo info; |
720 | string err_msg; | |
721 | http_ret = user.info(info, &err_msg); | |
722 | if (http_ret < 0) | |
723 | return; | |
724 | ||
725 | flusher.start(0); | |
726 | if (show_all) { | |
727 | UserQuotas quotas(info); | |
728 | encode_json("quota", quotas, s->formatter); | |
729 | } else if (show_user) { | |
730 | encode_json("user_quota", info.user_quota, s->formatter); | |
731 | } else { | |
732 | encode_json("bucket_quota", info.bucket_quota, s->formatter); | |
733 | } | |
734 | ||
735 | flusher.flush(); | |
736 | } | |
737 | ||
738 | class RGWOp_Quota_Set : public RGWRESTOp { | |
739 | ||
740 | public: | |
741 | RGWOp_Quota_Set() {} | |
742 | ||
743 | int check_caps(RGWUserCaps& caps) override { | |
744 | return caps.check_cap("users", RGW_CAP_WRITE); | |
745 | } | |
746 | ||
747 | void execute() override; | |
748 | ||
749 | const string name() override { return "set_quota_info"; } | |
750 | }; | |
751 | ||
752 | /** | |
753 | * set quota | |
754 | * | |
755 | * two different ways to set the quota info: as json struct in the message body or via http params. | |
756 | * | |
757 | * as json: | |
758 | * | |
759 | * PUT /admin/user?uid=<uid>["a-type=<type>] | |
760 | * | |
761 | * whereas quota-type is optional and is either user, or bucket | |
762 | * | |
763 | * if quota-type is not specified then we expect to get a structure that contains both quotas, | |
764 | * otherwise we'll only get the relevant configuration. | |
765 | * | |
766 | * E.g., if quota type not specified: | |
767 | * { | |
768 | * "user_quota" : { | |
769 | * "max_size_kb" : 4096, | |
770 | * "max_objects" : -1, | |
771 | * "enabled" : false | |
772 | * }, | |
773 | * "bucket_quota" : { | |
774 | * "max_size_kb" : 1024, | |
775 | * "max_objects" : -1, | |
776 | * "enabled" : true | |
777 | * } | |
778 | * } | |
779 | * | |
780 | * | |
781 | * or if quota type is specified: | |
782 | * { | |
783 | * "max_size_kb" : 4096, | |
784 | * "max_objects" : -1, | |
785 | * "enabled" : false | |
786 | * } | |
787 | * | |
788 | * Another option is not to pass any body and set the following http params: | |
789 | * | |
790 | * | |
791 | * max-size-kb=<size> | |
792 | * max-objects=<max objects> | |
793 | * enabled[={true,false}] | |
794 | * | |
795 | * all params are optionals and default to the current settings. With this type of configuration the | |
796 | * quota-type param is mandatory. | |
797 | * | |
798 | */ | |
799 | ||
800 | void RGWOp_Quota_Set::execute() | |
801 | { | |
802 | RGWUserAdminOpState op_state; | |
803 | ||
804 | std::string uid_str; | |
805 | std::string quota_type; | |
806 | ||
807 | RESTArgs::get_string(s, "uid", uid_str, &uid_str); | |
808 | RESTArgs::get_string(s, "quota-type", quota_type, "a_type); | |
809 | ||
810 | if (uid_str.empty()) { | |
811 | http_ret = -EINVAL; | |
812 | return; | |
813 | } | |
814 | ||
815 | rgw_user uid(uid_str); | |
816 | ||
817 | bool set_all = quota_type.empty(); | |
818 | bool set_bucket = set_all || (quota_type == "bucket"); | |
819 | bool set_user = set_all || (quota_type == "user"); | |
820 | ||
821 | if (!(set_all || set_bucket || set_user)) { | |
822 | ldout(store->ctx(), 20) << "invalid quota type" << dendl; | |
823 | http_ret = -EINVAL; | |
824 | return; | |
825 | } | |
826 | ||
827 | bool use_http_params; | |
828 | ||
829 | if (s->content_length > 0) { | |
830 | use_http_params = false; | |
831 | } else { | |
832 | const char *encoding = s->info.env->get("HTTP_TRANSFER_ENCODING"); | |
833 | use_http_params = (!encoding || strcmp(encoding, "chunked") != 0); | |
834 | } | |
835 | ||
836 | if (use_http_params && set_all) { | |
837 | ldout(store->ctx(), 20) << "quota type was not specified, can't set all quotas via http headers" << dendl; | |
838 | http_ret = -EINVAL; | |
839 | return; | |
840 | } | |
841 | ||
842 | op_state.set_user_id(uid); | |
843 | ||
844 | RGWUser user; | |
845 | http_ret = user.init(store, op_state); | |
846 | if (http_ret < 0) { | |
847 | ldout(store->ctx(), 20) << "failed initializing user info: " << http_ret << dendl; | |
848 | return; | |
849 | } | |
850 | ||
224ce89b WB |
851 | if (!op_state.has_existing_user()) { |
852 | http_ret = -ERR_NO_SUCH_USER; | |
853 | return; | |
854 | } | |
855 | ||
7c673cae FG |
856 | #define QUOTA_INPUT_MAX_LEN 1024 |
857 | if (set_all) { | |
858 | UserQuotas quotas; | |
859 | ||
860 | if ((http_ret = rgw_rest_get_json_input(store->ctx(), s, quotas, QUOTA_INPUT_MAX_LEN, NULL)) < 0) { | |
861 | ldout(store->ctx(), 20) << "failed to retrieve input" << dendl; | |
862 | return; | |
863 | } | |
864 | ||
865 | op_state.set_user_quota(quotas.user_quota); | |
866 | op_state.set_bucket_quota(quotas.bucket_quota); | |
867 | } else { | |
868 | RGWQuotaInfo quota; | |
869 | ||
870 | if (!use_http_params) { | |
871 | bool empty; | |
872 | http_ret = rgw_rest_get_json_input(store->ctx(), s, quota, QUOTA_INPUT_MAX_LEN, &empty); | |
873 | if (http_ret < 0) { | |
874 | ldout(store->ctx(), 20) << "failed to retrieve input" << dendl; | |
875 | if (!empty) | |
876 | return; | |
877 | ||
878 | /* was probably chunked input, but no content provided, configure via http params */ | |
879 | use_http_params = true; | |
880 | } | |
881 | } | |
882 | ||
883 | if (use_http_params) { | |
884 | RGWUserInfo info; | |
885 | string err_msg; | |
886 | http_ret = user.info(info, &err_msg); | |
887 | if (http_ret < 0) { | |
888 | ldout(store->ctx(), 20) << "failed to get user info: " << http_ret << dendl; | |
889 | return; | |
890 | } | |
891 | RGWQuotaInfo *old_quota; | |
892 | if (set_user) { | |
893 | old_quota = &info.user_quota; | |
894 | } else { | |
895 | old_quota = &info.bucket_quota; | |
896 | } | |
897 | ||
898 | int64_t old_max_size_kb = rgw_rounded_kb(old_quota->max_size); | |
899 | int64_t max_size_kb; | |
900 | RESTArgs::get_int64(s, "max-objects", old_quota->max_objects, "a.max_objects); | |
901 | RESTArgs::get_int64(s, "max-size-kb", old_max_size_kb, &max_size_kb); | |
902 | quota.max_size = max_size_kb * 1024; | |
903 | RESTArgs::get_bool(s, "enabled", old_quota->enabled, "a.enabled); | |
904 | } | |
905 | ||
906 | if (set_user) { | |
907 | op_state.set_user_quota(quota); | |
908 | } else { | |
909 | op_state.set_bucket_quota(quota); | |
910 | } | |
911 | } | |
912 | ||
913 | string err; | |
914 | http_ret = user.modify(op_state, &err); | |
915 | if (http_ret < 0) { | |
916 | ldout(store->ctx(), 20) << "failed updating user info: " << http_ret << ": " << err << dendl; | |
917 | return; | |
918 | } | |
919 | } | |
920 | ||
921 | RGWOp *RGWHandler_User::op_get() | |
922 | { | |
923 | if (s->info.args.sub_resource_exists("quota")) | |
924 | return new RGWOp_Quota_Info; | |
925 | ||
926 | return new RGWOp_User_Info; | |
927 | } | |
928 | ||
929 | RGWOp *RGWHandler_User::op_put() | |
930 | { | |
931 | if (s->info.args.sub_resource_exists("subuser")) | |
932 | return new RGWOp_Subuser_Create; | |
933 | ||
934 | if (s->info.args.sub_resource_exists("key")) | |
935 | return new RGWOp_Key_Create; | |
936 | ||
937 | if (s->info.args.sub_resource_exists("caps")) | |
938 | return new RGWOp_Caps_Add; | |
939 | ||
940 | if (s->info.args.sub_resource_exists("quota")) | |
941 | return new RGWOp_Quota_Set; | |
942 | ||
943 | return new RGWOp_User_Create; | |
944 | } | |
945 | ||
946 | RGWOp *RGWHandler_User::op_post() | |
947 | { | |
948 | if (s->info.args.sub_resource_exists("subuser")) | |
949 | return new RGWOp_Subuser_Modify; | |
950 | ||
951 | return new RGWOp_User_Modify; | |
952 | } | |
953 | ||
954 | RGWOp *RGWHandler_User::op_delete() | |
955 | { | |
956 | if (s->info.args.sub_resource_exists("subuser")) | |
957 | return new RGWOp_Subuser_Remove; | |
958 | ||
959 | if (s->info.args.sub_resource_exists("key")) | |
960 | return new RGWOp_Key_Remove; | |
961 | ||
962 | if (s->info.args.sub_resource_exists("caps")) | |
963 | return new RGWOp_Caps_Remove; | |
964 | ||
965 | return new RGWOp_User_Remove; | |
966 | } | |
967 |