From 7793b38c19ada261a04e6217aca78da47aa40c4b Mon Sep 17 00:00:00 2001 From: Kanika Murarka Date: Fri, 30 Nov 2018 11:06:00 +0530 Subject: [PATCH] mgr/dashboard: Validation for duplicate RGW user email Fixes: http://tracker.ceph.com/issues/37369 Signed-off-by: Kanika Murarka --- src/pybind/mgr/dashboard/controllers/rgw.py | 10 ++ .../rgw-user-form.component.html | 3 + .../rgw-user-form/rgw-user-form.component.ts | 6 +- .../src/app/shared/api/rgw-user.service.ts | 18 +++ .../frontend/src/locale/messages.xlf | 108 +++++++++--------- 5 files changed, 93 insertions(+), 52 deletions(-) diff --git a/src/pybind/mgr/dashboard/controllers/rgw.py b/src/pybind/mgr/dashboard/controllers/rgw.py index e533287df27..07429cad590 100644 --- a/src/pybind/mgr/dashboard/controllers/rgw.py +++ b/src/pybind/mgr/dashboard/controllers/rgw.py @@ -174,6 +174,16 @@ class RgwUser(RgwRESTController): result = self.proxy('GET', 'user', {'uid': uid}) return self._append_uid(result) + @Endpoint() + @ReadPermission + def get_emails(self): + emails = [] + for uid in json.loads(self.list()): + user = json.loads(self.get(uid)) + if user["email"]: + emails.append(user["email"]) + return emails + def create(self, uid, display_name, email=None, max_buckets=None, suspended=None, generate_key=None, access_key=None, secret_key=None): diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html index 88466bbb1f9..2ed89951341 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html @@ -77,6 +77,9 @@ This is not a valid email address. + The chosen email address is already in use. diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts index db8ebd178d8..f1f873d9965 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts @@ -57,7 +57,11 @@ export class RgwUserFormComponent implements OnInit { [CdValidators.unique(this.rgwUserService.exists, this.rgwUserService)] ], display_name: [null, [Validators.required]], - email: [null, [CdValidators.email]], + email: [ + null, + [CdValidators.email], + [CdValidators.unique(this.rgwUserService.emailExists, this.rgwUserService)] + ], max_buckets: [1000, [Validators.required, Validators.min(0)]], suspended: [false], // S3 key diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user.service.ts index 07b05b78b01..25891d2649a 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user.service.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user.service.ts @@ -44,6 +44,10 @@ export class RgwUserService { return this.http.get(this.url); } + enumerateEmail() { + return this.http.get(`${this.url}/get_emails`); + } + get(uid: string) { return this.http.get(`${this.url}/${uid}`); } @@ -135,4 +139,18 @@ export class RgwUserService { }) ); } + + // Using @cdEncodeNot would be the preferred way here, but this + // causes an error: https://tracker.ceph.com/issues/37505 + // Use decodeURIComponent as workaround. + // emailExists(@cdEncodeNot email: string): Observable { + emailExists(email: string): Observable { + email = decodeURIComponent(email); + return this.enumerateEmail().pipe( + mergeMap((resp: any[]) => { + const index = _.indexOf(resp, email); + return observableOf(-1 !== index); + }) + ); + } } diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.xlf index 11343488773..5e1a561ea29 100644 --- a/src/pybind/mgr/dashboard/frontend/src/locale/messages.xlf +++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.xlf @@ -210,7 +210,7 @@ app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 595 + 598 app/core/auth/role-form/role-form.component.html @@ -415,31 +415,31 @@ app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 98 + 101 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 163 + 166 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 195 + 198 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 446 + 449 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 483 + 486 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 539 + 542 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 576 + 579 app/core/auth/role-form/role-form.component.html @@ -655,11 +655,11 @@ app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 232 + 235 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 371 + 374 Description @@ -1567,11 +1567,11 @@ app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 449 + 452 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 542 + 545 The chosen name is already in use. @@ -1615,7 +1615,7 @@ app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 590 + 593 Daemons List @@ -1673,7 +1673,7 @@ app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 120 + 123 Username @@ -1715,7 +1715,7 @@ app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 130 + 133 Access key @@ -1725,7 +1725,7 @@ app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 141 + 144 Secret key @@ -1743,7 +1743,7 @@ app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 173 + 176 Subuser @@ -1837,31 +1837,37 @@ app/ceph/rgw/rgw-user-form/rgw-user-form.component.html 79 + + The chosen email address is already in use. + + app/ceph/rgw/rgw-user-form/rgw-user-form.component.html + 82 + Max. buckets app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 88 + 91 The entered value must be >= 0. app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 101 + 104 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 486 + 489 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 579 + 582 Suspended app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 113 + 116 app/ceph/rgw/rgw-user-details/rgw-user-details.component.html @@ -1871,7 +1877,7 @@ Subusers app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 202 + 205 app/ceph/rgw/rgw-user-details/rgw-user-details.component.html @@ -1881,33 +1887,33 @@ There are no subusers. app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 208 + 211 Delete app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 239 + 242 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 293 + 296 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 378 + 381 Add subuser app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 253 + 256 Keys app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 261 + 264 app/ceph/rgw/rgw-user-details/rgw-user-details.component.html @@ -1917,27 +1923,27 @@ S3 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 265 + 268 There are no keys. app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 270 + 273 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 320 + 323 Show app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 286 + 289 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 336 + 339 app/ceph/rgw/rgw-user-details/rgw-user-details.component.html @@ -1947,19 +1953,19 @@ Add S3 key app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 307 + 310 Swift app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 315 + 318 Capabilities app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 349 + 352 app/ceph/rgw/rgw-user-details/rgw-user-details.component.html @@ -1969,19 +1975,19 @@ There are no capabilities. app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 355 + 358 Add capability app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 392 + 395 User quota app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 400 + 403 app/ceph/rgw/rgw-user-details/rgw-user-details.component.html @@ -1991,11 +1997,11 @@ Enabled app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 410 + 413 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 503 + 506 app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html @@ -2013,47 +2019,47 @@ Unlimited size app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 424 + 427 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 517 + 520 Max. size app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 435 + 438 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 528 + 531 Unlimited objects app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 462 + 465 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 555 + 558 Max. objects app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 473 + 476 app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 566 + 569 Bucket quota app/ceph/rgw/rgw-user-form/rgw-user-form.component.html - 493 + 496 app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html -- 2.39.5