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