]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_rest_user.cc
update sources to v12.1.1
[ceph.git] / ceph / src / rgw / rgw_rest_user.cc
CommitLineData
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
15class RGWOp_User_Info : public RGWRESTOp {
16
17public:
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
29void 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
56class RGWOp_User_Create : public RGWRESTOp {
57
58public:
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
70void 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
178class RGWOp_User_Modify : public RGWRESTOp {
179
180public:
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
192void 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
263class RGWOp_User_Remove : public RGWRESTOp {
264
265public:
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
277void 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
298class RGWOp_Subuser_Create : public RGWRESTOp {
299
300public:
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
312void 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
368class RGWOp_Subuser_Modify : public RGWRESTOp {
369
370public:
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
382void 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
425class RGWOp_Subuser_Remove : public RGWRESTOp {
426
427public:
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
439void 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
462class RGWOp_Key_Create : public RGWRESTOp {
463
464public:
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
476void 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
518class RGWOp_Key_Remove : public RGWRESTOp {
519
520public:
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
532void 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
565class RGWOp_Caps_Add : public RGWRESTOp {
566
567public:
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
579void 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
597class RGWOp_Caps_Remove : public RGWRESTOp {
598
599public:
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
611void 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
629struct 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
648class RGWOp_Quota_Info : public RGWRESTOp {
649
650public:
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
663void 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
224ce89b
WB
696 if (!op_state.has_existing_user()) {
697 http_ret = -ERR_NO_SUCH_USER;
698 return;
699 }
700
7c673cae
FG
701 RGWUserInfo info;
702 string err_msg;
703 http_ret = user.info(info, &err_msg);
704 if (http_ret < 0)
705 return;
706
707 flusher.start(0);
708 if (show_all) {
709 UserQuotas quotas(info);
710 encode_json("quota", quotas, s->formatter);
711 } else if (show_user) {
712 encode_json("user_quota", info.user_quota, s->formatter);
713 } else {
714 encode_json("bucket_quota", info.bucket_quota, s->formatter);
715 }
716
717 flusher.flush();
718}
719
720class RGWOp_Quota_Set : public RGWRESTOp {
721
722public:
723 RGWOp_Quota_Set() {}
724
725 int check_caps(RGWUserCaps& caps) override {
726 return caps.check_cap("users", RGW_CAP_WRITE);
727 }
728
729 void execute() override;
730
731 const string name() override { return "set_quota_info"; }
732};
733
734/**
735 * set quota
736 *
737 * two different ways to set the quota info: as json struct in the message body or via http params.
738 *
739 * as json:
740 *
741 * PUT /admin/user?uid=<uid>[&quota-type=<type>]
742 *
743 * whereas quota-type is optional and is either user, or bucket
744 *
745 * if quota-type is not specified then we expect to get a structure that contains both quotas,
746 * otherwise we'll only get the relevant configuration.
747 *
748 * E.g., if quota type not specified:
749 * {
750 * "user_quota" : {
751 * "max_size_kb" : 4096,
752 * "max_objects" : -1,
753 * "enabled" : false
754 * },
755 * "bucket_quota" : {
756 * "max_size_kb" : 1024,
757 * "max_objects" : -1,
758 * "enabled" : true
759 * }
760 * }
761 *
762 *
763 * or if quota type is specified:
764 * {
765 * "max_size_kb" : 4096,
766 * "max_objects" : -1,
767 * "enabled" : false
768 * }
769 *
770 * Another option is not to pass any body and set the following http params:
771 *
772 *
773 * max-size-kb=<size>
774 * max-objects=<max objects>
775 * enabled[={true,false}]
776 *
777 * all params are optionals and default to the current settings. With this type of configuration the
778 * quota-type param is mandatory.
779 *
780 */
781
782void RGWOp_Quota_Set::execute()
783{
784 RGWUserAdminOpState op_state;
785
786 std::string uid_str;
787 std::string quota_type;
788
789 RESTArgs::get_string(s, "uid", uid_str, &uid_str);
790 RESTArgs::get_string(s, "quota-type", quota_type, &quota_type);
791
792 if (uid_str.empty()) {
793 http_ret = -EINVAL;
794 return;
795 }
796
797 rgw_user uid(uid_str);
798
799 bool set_all = quota_type.empty();
800 bool set_bucket = set_all || (quota_type == "bucket");
801 bool set_user = set_all || (quota_type == "user");
802
803 if (!(set_all || set_bucket || set_user)) {
804 ldout(store->ctx(), 20) << "invalid quota type" << dendl;
805 http_ret = -EINVAL;
806 return;
807 }
808
809 bool use_http_params;
810
811 if (s->content_length > 0) {
812 use_http_params = false;
813 } else {
814 const char *encoding = s->info.env->get("HTTP_TRANSFER_ENCODING");
815 use_http_params = (!encoding || strcmp(encoding, "chunked") != 0);
816 }
817
818 if (use_http_params && set_all) {
819 ldout(store->ctx(), 20) << "quota type was not specified, can't set all quotas via http headers" << dendl;
820 http_ret = -EINVAL;
821 return;
822 }
823
824 op_state.set_user_id(uid);
825
826 RGWUser user;
827 http_ret = user.init(store, op_state);
828 if (http_ret < 0) {
829 ldout(store->ctx(), 20) << "failed initializing user info: " << http_ret << dendl;
830 return;
831 }
832
224ce89b
WB
833 if (!op_state.has_existing_user()) {
834 http_ret = -ERR_NO_SUCH_USER;
835 return;
836 }
837
7c673cae
FG
838#define QUOTA_INPUT_MAX_LEN 1024
839 if (set_all) {
840 UserQuotas quotas;
841
842 if ((http_ret = rgw_rest_get_json_input(store->ctx(), s, quotas, QUOTA_INPUT_MAX_LEN, NULL)) < 0) {
843 ldout(store->ctx(), 20) << "failed to retrieve input" << dendl;
844 return;
845 }
846
847 op_state.set_user_quota(quotas.user_quota);
848 op_state.set_bucket_quota(quotas.bucket_quota);
849 } else {
850 RGWQuotaInfo quota;
851
852 if (!use_http_params) {
853 bool empty;
854 http_ret = rgw_rest_get_json_input(store->ctx(), s, quota, QUOTA_INPUT_MAX_LEN, &empty);
855 if (http_ret < 0) {
856 ldout(store->ctx(), 20) << "failed to retrieve input" << dendl;
857 if (!empty)
858 return;
859
860 /* was probably chunked input, but no content provided, configure via http params */
861 use_http_params = true;
862 }
863 }
864
865 if (use_http_params) {
866 RGWUserInfo info;
867 string err_msg;
868 http_ret = user.info(info, &err_msg);
869 if (http_ret < 0) {
870 ldout(store->ctx(), 20) << "failed to get user info: " << http_ret << dendl;
871 return;
872 }
873 RGWQuotaInfo *old_quota;
874 if (set_user) {
875 old_quota = &info.user_quota;
876 } else {
877 old_quota = &info.bucket_quota;
878 }
879
880 int64_t old_max_size_kb = rgw_rounded_kb(old_quota->max_size);
881 int64_t max_size_kb;
882 RESTArgs::get_int64(s, "max-objects", old_quota->max_objects, &quota.max_objects);
883 RESTArgs::get_int64(s, "max-size-kb", old_max_size_kb, &max_size_kb);
884 quota.max_size = max_size_kb * 1024;
885 RESTArgs::get_bool(s, "enabled", old_quota->enabled, &quota.enabled);
886 }
887
888 if (set_user) {
889 op_state.set_user_quota(quota);
890 } else {
891 op_state.set_bucket_quota(quota);
892 }
893 }
894
895 string err;
896 http_ret = user.modify(op_state, &err);
897 if (http_ret < 0) {
898 ldout(store->ctx(), 20) << "failed updating user info: " << http_ret << ": " << err << dendl;
899 return;
900 }
901}
902
903RGWOp *RGWHandler_User::op_get()
904{
905 if (s->info.args.sub_resource_exists("quota"))
906 return new RGWOp_Quota_Info;
907
908 return new RGWOp_User_Info;
909}
910
911RGWOp *RGWHandler_User::op_put()
912{
913 if (s->info.args.sub_resource_exists("subuser"))
914 return new RGWOp_Subuser_Create;
915
916 if (s->info.args.sub_resource_exists("key"))
917 return new RGWOp_Key_Create;
918
919 if (s->info.args.sub_resource_exists("caps"))
920 return new RGWOp_Caps_Add;
921
922 if (s->info.args.sub_resource_exists("quota"))
923 return new RGWOp_Quota_Set;
924
925 return new RGWOp_User_Create;
926}
927
928RGWOp *RGWHandler_User::op_post()
929{
930 if (s->info.args.sub_resource_exists("subuser"))
931 return new RGWOp_Subuser_Modify;
932
933 return new RGWOp_User_Modify;
934}
935
936RGWOp *RGWHandler_User::op_delete()
937{
938 if (s->info.args.sub_resource_exists("subuser"))
939 return new RGWOp_Subuser_Remove;
940
941 if (s->info.args.sub_resource_exists("key"))
942 return new RGWOp_Key_Remove;
943
944 if (s->info.args.sub_resource_exists("caps"))
945 return new RGWOp_Caps_Remove;
946
947 return new RGWOp_User_Remove;
948}
949