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