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