k2hr3-api 1.0.26 → 1.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ChangeLog CHANGED
@@ -1,3 +1,9 @@
1
+ k2hr3-api (1.0.27) unstable; urgency=low
2
+
3
+ * Updated TENANT API and fixed bugs in TENANT API - #104
4
+
5
+ -- Takeshi Nakatani <ggtakec@gmail.com> Tue, 25 Jul 2023 16:16:10 +0900
6
+
1
7
  k2hr3-api (1.0.26) unstable; urgency=low
2
8
 
3
9
  * Added response object members in userToken GET API - #102
package/lib/k2hr3dkc.js CHANGED
@@ -2226,8 +2226,80 @@ function rawRemoveUserFromTenant(dkcobj_permanent, tenant, user)
2226
2226
  }
2227
2227
 
2228
2228
  //---------------------------------------------------------
2229
- // Common remove user from local tenant
2229
+ // Common remove local tenant
2230
2230
  //---------------------------------------------------------
2231
+ // tenant : tenant name
2232
+ // id : tenant id
2233
+ //
2234
+ // result : true/false
2235
+ //
2236
+ function rawRemoveLocalTenantEx(dkcobj_permanent, tenant, user, id)
2237
+ {
2238
+ if(!(dkcobj_permanent instanceof Object) || !dkcobj_permanent.isPermanent()){
2239
+ r3logger.elog('parameter dkcobj_permanent is not object or not permanent');
2240
+ return false;
2241
+ }
2242
+
2243
+ if(!apiutil.isSafeStrings(tenant, user, id)){
2244
+ r3logger.elog('some parameters are wrong : tenant=' + JSON.stringify(tenant) + ', user=' + JSON.stringify(user) + ', id=' + JSON.stringify(id));
2245
+ return false;
2246
+ }
2247
+
2248
+ //
2249
+ // Keys
2250
+ //
2251
+ var keys = r3keys(user, tenant);
2252
+
2253
+ //
2254
+ // Check tenant name
2255
+ //
2256
+ if(0 !== tenant.indexOf(keys.VALUE_PREFIX_LOCAL_TENANT)){
2257
+ // Not have prefix("local@")
2258
+ r3logger.elog('tenant(' + tenant + ') must be start ' + keys.VALUE_PREFIX_LOCAL_TENANT + ' prefix for local tenant.');
2259
+ return false;
2260
+ }
2261
+
2262
+ //
2263
+ // Find tenant
2264
+ //
2265
+ var result = rawFindTenantEx(dkcobj_permanent, tenant, user, id);
2266
+ if(!apiutil.isSafeEntity(result)){
2267
+ r3logger.elog('could not find tenant(' + tenant + ') with user=' + JSON.stringify(user) + ' and id=' + JSON.stringify(id));
2268
+ return false;
2269
+ }
2270
+
2271
+ //
2272
+ // Check user in tenant user list
2273
+ //
2274
+ if(!apiutil.findStringInArray(result.users, user)){
2275
+ r3logger.elog('user(' + user + ') is not tenant(' + tenant + ') user member.');
2276
+ return false;
2277
+ }
2278
+
2279
+ //
2280
+ // Remove all user from tenant
2281
+ //
2282
+ // [NOTE]
2283
+ // Deleting all users of a tenant automatically deletes the tenant.
2284
+ //
2285
+ var error = false;
2286
+ if(apiutil.isArray(result.users)){
2287
+ for(var cnt = 0; cnt < result.users.length; ++cnt){
2288
+ var delete_user_name = result.users[cnt].replace(keys.USER_TOP_KEY + ':', '');
2289
+ if(!rawRemoveUserFromLocalTenantEx(dkcobj_permanent, tenant, delete_user_name, id)){
2290
+ r3logger.elog('could not delete user(' + delete_user_name + ') from local tenant(' + tenant + '), id(' + id + '), but continue...');
2291
+ error = true;
2292
+ }
2293
+ }
2294
+ }
2295
+ if(error){
2296
+ r3logger.elog('failed to remove some user in local tenant.');
2297
+ return false;
2298
+ }
2299
+
2300
+ return true;
2301
+ }
2302
+
2231
2303
  // tenant : tenant name
2232
2304
  // user : user name
2233
2305
  // id : tenant id
@@ -2237,7 +2309,7 @@ function rawRemoveUserFromTenant(dkcobj_permanent, tenant, user)
2237
2309
  // message: null or error message
2238
2310
  // }
2239
2311
  //
2240
- function rawRemoveUserFromLocalTenant(tenant, user, id)
2312
+ function rawRemoveLocalTenant(tenant, user, id)
2241
2313
  {
2242
2314
  var resobj = {result: true, message: null};
2243
2315
 
@@ -2257,6 +2329,39 @@ function rawRemoveUserFromLocalTenant(tenant, user, id)
2257
2329
  return resobj;
2258
2330
  }
2259
2331
 
2332
+ if(!rawRemoveLocalTenantEx(dkcobj, tenant, user, id)){
2333
+ resobj.result = false;
2334
+ resobj.message = 'could not remove local tenant(' + JSON.stringify(tenant) + '), id(' + JSON.stringify(id) + ').';
2335
+ r3logger.elog(resobj.message);
2336
+ dkcobj.clean();
2337
+ return resobj;
2338
+ }
2339
+ dkcobj.clean();
2340
+
2341
+ return resobj;
2342
+ }
2343
+
2344
+ //---------------------------------------------------------
2345
+ // Common remove user from local tenant
2346
+ //---------------------------------------------------------
2347
+ // tenant : tenant name
2348
+ // user : user name
2349
+ // id : tenant id
2350
+ //
2351
+ // result : true/false
2352
+ //
2353
+ function rawRemoveUserFromLocalTenantEx(dkcobj_permanent, tenant, user, id)
2354
+ {
2355
+ if(!(dkcobj_permanent instanceof Object) || !dkcobj_permanent.isPermanent()){
2356
+ r3logger.elog('parameter dkcobj_permanent is not object or not permanent');
2357
+ return false;
2358
+ }
2359
+
2360
+ if(!apiutil.isSafeStrings(tenant, user, id)){
2361
+ r3logger.elog('some parameters are wrong : tenant=' + JSON.stringify(tenant) + ', user=' + JSON.stringify(user) + ', id=' + JSON.stringify(id));
2362
+ return false;
2363
+ }
2364
+
2260
2365
  //
2261
2366
  // Keys
2262
2367
  //
@@ -2267,53 +2372,81 @@ function rawRemoveUserFromLocalTenant(tenant, user, id)
2267
2372
  //
2268
2373
  if(0 !== tenant.indexOf(keys.VALUE_PREFIX_LOCAL_TENANT)){
2269
2374
  // Not have prefix("local@")
2270
- resobj.result = false;
2271
- resobj.message = 'tenant(' + tenant + ') must be start ' + keys.VALUE_PREFIX_LOCAL_TENANT + ' prefix for local tenant.';
2272
- r3logger.elog(resobj.message);
2273
- dkcobj.clean();
2274
- return resobj;
2375
+ r3logger.elog('tenant(' + tenant + ') must be start ' + keys.VALUE_PREFIX_LOCAL_TENANT + ' prefix for local tenant.');
2376
+ return false;
2275
2377
  }
2276
2378
 
2277
2379
  //
2278
2380
  // Find tenant
2279
2381
  //
2280
- var result = rawFindTenantEx(dkcobj, tenant, user, id);
2382
+ var result = rawFindTenantEx(dkcobj_permanent, tenant, user, id);
2281
2383
  if(!apiutil.isSafeEntity(result)){
2282
- resobj.result = false;
2283
- resobj.message = 'could not find tenant(' + tenant + ') with user=' + JSON.stringify(user) + ' and id=' + JSON.stringify(id);
2284
- r3logger.elog(resobj.message);
2285
- dkcobj.clean();
2286
- return resobj;
2384
+ r3logger.elog('could not find tenant(' + tenant + ') with user=' + JSON.stringify(user) + ' and id=' + JSON.stringify(id));
2385
+ return false;
2287
2386
  }
2288
2387
 
2289
2388
  //
2290
2389
  // Check user list in tenant
2291
2390
  //
2292
2391
  if(!apiutil.findStringInArray(result.users, user)){
2293
- resobj.result = false;
2294
- resobj.message = 'user(' + user + ') is not tenant(' + tenant + ') member.';
2295
- r3logger.elog(resobj.message);
2296
- dkcobj.clean();
2297
- return resobj;
2392
+ r3logger.elog('user(' + user + ') is not tenant(' + tenant + ') member.');
2393
+ return false;
2298
2394
  }
2299
2395
 
2300
2396
  //
2301
2397
  // Remove tenant from user
2302
2398
  //
2303
- if(!rawRemoveTenantFromUser(dkcobj, user, tenant)){
2399
+ if(!rawRemoveTenantFromUser(dkcobj_permanent, user, tenant)){
2400
+ r3logger.elog('failed to remove tenant(' + tenant + ') from user(' + user + ').');
2401
+ return false;
2402
+ }
2403
+
2404
+ //
2405
+ // Remove user from tenant
2406
+ //
2407
+ // [NOTE]
2408
+ // If all users of a tenant disappear after deletion, the tenant is automatically deleted.
2409
+ //
2410
+ if(!rawRemoveUserFromTenant(dkcobj_permanent, tenant, user)){
2411
+ r3logger.elog('failed to remove user(' + user + ') from tenant(' + tenant + ').');
2412
+ return false;
2413
+ }
2414
+
2415
+ return true;
2416
+ }
2417
+
2418
+ // tenant : tenant name
2419
+ // user : user name
2420
+ // id : tenant id
2421
+ //
2422
+ // result {
2423
+ // result: true/false
2424
+ // message: null or error message
2425
+ // }
2426
+ //
2427
+ function rawRemoveUserFromLocalTenant(tenant, user, id)
2428
+ {
2429
+ var resobj = {result: true, message: null};
2430
+
2431
+ if(!apiutil.isSafeStrings(tenant, user, id)){
2304
2432
  resobj.result = false;
2305
- resobj.message = 'failed to remove tenant(' + tenant + ') from user(' + user + ').';
2433
+ resobj.message = 'some parameters are wrong : tenant=' + JSON.stringify(tenant) + ', user=' + JSON.stringify(user) + ', id=' + JSON.stringify(id);
2434
+ r3logger.elog(resobj.message);
2435
+ return resobj;
2436
+ }
2437
+
2438
+ var dkcobj = k2hdkc(dkcconf, dkcport, dkccuk, true, false); // use permanent object(need to clean)
2439
+ if(!rawInitKeyHierarchy(dkcobj)){
2440
+ resobj.result = false;
2441
+ resobj.message = 'Not initialize yet, or configuration is not set';
2306
2442
  r3logger.elog(resobj.message);
2307
2443
  dkcobj.clean();
2308
2444
  return resobj;
2309
2445
  }
2310
2446
 
2311
- //
2312
- // Remove user from tenant
2313
- //
2314
- if(!rawRemoveUserFromTenant(dkcobj, tenant, user)){
2447
+ if(!rawRemoveUserFromLocalTenantEx(dkcobj, tenant, user, id)){
2315
2448
  resobj.result = false;
2316
- resobj.message = 'failed to remove user(' + user + ') from tenant(' + tenant + ').';
2449
+ resobj.message = 'could not remove user(' + JSON.stringify(user) + ') from tenant(' + JSON.stringify(tenant) + '), id(' + JSON.stringify(id) + ').';
2317
2450
  r3logger.elog(resobj.message);
2318
2451
  dkcobj.clean();
2319
2452
  return resobj;
@@ -2387,14 +2520,14 @@ function rawAddTenantToExistedUser(dkcobj_permanent, user, tenant)
2387
2520
  // id : tenant id, if user is specified(service is specified, do not need this)
2388
2521
  // desc : tenant description, if user is specified(service is specified, do not need this)
2389
2522
  // display : display name, if user is specified(service is specified, do not need this)
2390
- // other_users : other users in this tenant (this parameter is invalid if service is specified)
2523
+ // tenant_users : tenant users in this tenant (this parameter is invalid if service is specified)
2391
2524
  //
2392
2525
  // [NOTE]
2393
2526
  // Both user and service can not be specified at same time.
2394
2527
  // This function create keys without resource/policy/role, you must be careful for service
2395
2528
  // case.
2396
2529
  //
2397
- function rawCreateTenantEx(dkcobj_permanent, user, tenant, service, id, desc, display, other_users)
2530
+ function rawCreateTenantEx(dkcobj_permanent, user, tenant, service, id, desc, display, tenant_users)
2398
2531
  {
2399
2532
  if(!(dkcobj_permanent instanceof Object) || !dkcobj_permanent.isPermanent()){
2400
2533
  r3logger.elog('parameter dkcobj_permanent is not object or not permanent');
@@ -2420,10 +2553,10 @@ function rawCreateTenantEx(dkcobj_permanent, user, tenant, service, id, desc, di
2420
2553
  }
2421
2554
  service = null;
2422
2555
 
2423
- if(apiutil.isEmptyArray(other_users)){
2424
- other_users = [];
2556
+ if(apiutil.isEmptyArray(tenant_users)){
2557
+ r3logger.elog('parameter is wrong : tenant_users=' + JSON.stringify(tenant_users));
2558
+ return false;
2425
2559
  }
2426
- apiutil.tryAddStringToArray(other_users, user); // add user to other_users
2427
2560
 
2428
2561
  }else if(apiutil.isSafeString(service) && !apiutil.isSafeString(user)){
2429
2562
  //
@@ -2431,7 +2564,7 @@ function rawCreateTenantEx(dkcobj_permanent, user, tenant, service, id, desc, di
2431
2564
  //
2432
2565
  service = service.toLowerCase();
2433
2566
  user = null;
2434
- other_users = null;
2567
+ tenant_users= null;
2435
2568
  }else{
2436
2569
  r3logger.elog('some parameters are wrong(both are empty or not empty) : service=' + JSON.stringify(service) + ', user=' + JSON.stringify(user));
2437
2570
  return false;
@@ -2661,32 +2794,42 @@ function rawCreateTenantEx(dkcobj_permanent, user, tenant, service, id, desc, di
2661
2794
  }
2662
2795
 
2663
2796
  //
2664
- // Add other users(with user) to tenant
2797
+ // Add tenant users to tenant
2665
2798
  //
2666
- if(!apiutil.isEmptyArray(other_users)){
2667
- var need_update_user_key = false;
2668
- for(var cnt = 0; cnt < other_users.length; ++cnt){
2669
- // add one other user
2670
- var added_other_user = rawAddTenantToExistedUser(dkcobj_permanent, other_users[cnt], tenant);
2671
- if(!apiutil.isSafeString(added_other_user)){
2672
- continue;
2673
- }
2674
- // check new adding user
2675
- if(apiutil.tryAddStringToArray(user_subkeylist, added_other_user)){
2676
- user_subkeylist.sort();
2677
- need_update_user_key = true;
2678
- }
2799
+ var new_user_subkeylist = [];
2800
+ for(var cnt = 0; cnt < tenant_users.length; ++cnt){
2801
+ // add one tenant user
2802
+ var added_other_user = rawAddTenantToExistedUser(dkcobj_permanent, tenant_users[cnt], tenant);
2803
+ if(!apiutil.isSafeString(added_other_user)){
2804
+ continue;
2679
2805
  }
2680
- //
2681
- // Re-update user key in tenant
2682
- //
2683
- if(need_update_user_key){
2684
- if(!dkcobj_permanent.setSubkeys(keys.TENANT_USER_KEY, user_subkeylist)){ // add subkey yrn:yahoo::::user:<user> -> yrn:yahoo:::<tenant>:user
2685
- r3logger.elog('could not add ' + keys.USER_KEY + ' subkey under ' + keys.TENANT_USER_KEY + ' key');
2686
- return false;
2687
- }
2806
+ // check new adding user
2807
+ if(apiutil.tryAddStringToArray(new_user_subkeylist, added_other_user)){
2808
+ new_user_subkeylist.sort();
2688
2809
  }
2689
2810
  }
2811
+
2812
+ //
2813
+ // Delete tenant users
2814
+ //
2815
+ for(cnt = 0; cnt < user_subkeylist.length; ++cnt){
2816
+ if(apiutil.findStringInArray(new_user_subkeylist, user_subkeylist[cnt])){
2817
+ continue;
2818
+ }
2819
+ // user does not in new tenant users
2820
+ var delete_user_name = user_subkeylist[cnt].replace(keys.USER_TOP_KEY + ':', '');
2821
+ if(!rawRemoveUserFromLocalTenantEx(dkcobj_permanent, tenant, delete_user_name, id)){
2822
+ r3logger.elog('could not delete user(' + delete_user_name + ') from tenant(' + tenant + '), id(' + id + '), but continue...');
2823
+ }
2824
+ }
2825
+
2826
+ //
2827
+ // Re-update user key in tenant(always update...)
2828
+ //
2829
+ if(!dkcobj_permanent.setSubkeys(keys.TENANT_USER_KEY, new_user_subkeylist)){ // add subkey yrn:yahoo::::user:<user> -> yrn:yahoo:::<tenant>:user
2830
+ r3logger.elog('could not add ' + keys.USER_KEY + ' subkey under ' + keys.TENANT_USER_KEY + ' key');
2831
+ return false;
2832
+ }
2690
2833
  }
2691
2834
 
2692
2835
  //
@@ -2856,13 +2999,14 @@ function rawCheckTenantEnable(dkcobj_permanent, tenant, servicename)
2856
2999
  // id : tenant id
2857
3000
  // desc : tenant description
2858
3001
  // display : display name
2859
- // other_users : other users in this tenant (this parameter is invalid if service is specified)
3002
+ // tenant_users : tenant users in this tenant (this parameter is invalid if service is specified)
3003
+ // is_replace_users: replace with tenant_users if this flag is true (default). if false, tenant_users will be added.
2860
3004
  //
2861
3005
  // [NOTE]
2862
3006
  // This function does not check the user is a member in tenant, then
2863
3007
  // you must check it before calling this function.
2864
3008
  //
2865
- function rawCreateTenant(user, tenant, id, desc, display, other_users)
3009
+ function rawCreateTenant(user, tenant, id, desc, display, tenant_users, is_replace_users)
2866
3010
  {
2867
3011
  var resobj = {result: true, message: null};
2868
3012
 
@@ -2884,6 +3028,19 @@ function rawCreateTenant(user, tenant, id, desc, display, other_users)
2884
3028
  // to string
2885
3029
  id = String(id);
2886
3030
  }
3031
+ if(!apiutil.isArray(tenant_users) && !apiutil.isSafeString(tenant_users)){
3032
+ // tenant_users must be array or string
3033
+ //
3034
+ resobj.result = false;
3035
+ resobj.message = 'parameter is wrong : tenant_users=' + JSON.stringify(tenant_users);
3036
+ r3logger.elog(resobj.message);
3037
+ return resobj;
3038
+ }else if(!apiutil.isArray(tenant_users)){
3039
+ tenant_users = [tenant_users];
3040
+ }
3041
+ if('boolean' !== typeof is_replace_users){
3042
+ is_replace_users = true;
3043
+ }
2887
3044
 
2888
3045
  var dkcobj = k2hdkc(dkcconf, dkcport, dkccuk, true, false); // use permanent object(need to clean)
2889
3046
  if(!rawInitKeyHierarchy(dkcobj)){
@@ -2894,10 +3051,19 @@ function rawCreateTenant(user, tenant, id, desc, display, other_users)
2894
3051
  return resobj;
2895
3052
  }
2896
3053
 
3054
+ if(!is_replace_users){
3055
+ var findobj = rawFindTenantEx(dkcobj, tenant, user, id);
3056
+ if(apiutil.isSafeEntity(findobj)){
3057
+ // found tenant
3058
+ tenant_users = apiutil.mergeArray(tenant_users, apiutil.getSafeArray(findobj.users));
3059
+ tenant_users.sort();
3060
+ }
3061
+ }
3062
+
2897
3063
  //
2898
3064
  // Create tenant top
2899
3065
  //
2900
- if(!rawCreateTenantEx(dkcobj, user, tenant, null, id, desc, display, other_users)){
3066
+ if(!rawCreateTenantEx(dkcobj, user, tenant, null, id, desc, display, tenant_users)){
2901
3067
  resobj.result = false;
2902
3068
  resobj.message = 'could not create tenant(' + tenant + ') with id(' + id + '), desc(' + JSON.stringify(desc) + '), display(' + JSON.stringify(display) + '), user(' + user + ')';
2903
3069
  r3logger.elog(resobj.message);
@@ -11783,12 +11949,12 @@ function rawCompareChildrenListName(child1, child2)
11783
11949
  //
11784
11950
  // These functions initializing tenant is without service.
11785
11951
  //
11786
- exports.initTenant = function(tenantname, id, desc, display, user, other_users)
11952
+ exports.initTenant = function(tenantname, id, desc, display, user, tenant_users)
11787
11953
  {
11788
11954
  //
11789
11955
  // Must initialize service key before calling this if specified service parameter
11790
11956
  //
11791
- return rawCreateTenant(user, tenantname, id, desc, display, other_users);
11957
+ return rawCreateTenant(user, tenantname, id, desc, display, tenant_users, true);
11792
11958
  };
11793
11959
 
11794
11960
  exports.initUser = function(user, id, username, tenant)
@@ -11801,7 +11967,7 @@ exports.initUserTenant = function(user, userid, username, tenant, tenantid, tena
11801
11967
  //
11802
11968
  // Must initialize service key before calling this if specified service parameter
11803
11969
  //
11804
- var resobj = rawCreateTenant(user, tenant, tenantid, tenantdesc, tenantdisplay);
11970
+ var resobj = rawCreateTenant(user, tenant, tenantid, tenantdesc, tenantdisplay, user, false);
11805
11971
  if(resobj.result){
11806
11972
  resobj = rawCreateUser(user, userid, username, tenant);
11807
11973
  }
@@ -11823,6 +11989,11 @@ exports.removeUserFromLocalTenant = function(tenant, user, id)
11823
11989
  return rawRemoveUserFromLocalTenant(tenant, user, id);
11824
11990
  };
11825
11991
 
11992
+ exports.removeLocalTenant = function(tenant, user, id)
11993
+ {
11994
+ return rawRemoveLocalTenant(tenant, user, id);
11995
+ };
11996
+
11826
11997
  exports.getUserId = function(username)
11827
11998
  {
11828
11999
  return rawGetUserId(username);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "k2hr3-api",
3
- "version": "1.0.26",
3
+ "version": "1.0.27",
4
4
  "dependencies": {
5
5
  "@kubernetes/client-node": "^0.18.1",
6
6
  "body-parser": "^1.20.2",
@@ -12,7 +12,7 @@
12
12
  "jose": "^4.14.4",
13
13
  "k2hdkc": "^1.0.5",
14
14
  "morgan": "~1.10.0",
15
- "rotating-file-stream": "^3.1.0"
15
+ "rotating-file-stream": "^3.1.1"
16
16
  },
17
17
  "bin": {
18
18
  "k2hr3-api": "./bin/www",
@@ -30,12 +30,12 @@
30
30
  "devDependencies": {
31
31
  "chai": "^4.3.7",
32
32
  "chai-http": "^4.4.0",
33
- "eslint": "^8.44.0",
33
+ "eslint": "^8.45.0",
34
34
  "mocha": "^10.2.0",
35
35
  "nyc": "^15.1.0"
36
36
  },
37
37
  "scripts": {
38
- "help": "echo 'command list:\n npm run start\n npm run start:prod\n npm run start:production\n npm run start:prod:dbg\n npm run start:prod:debug\n npm run start:prod:debug:break\n npm run start:prod:debug:nobreak\n npm run start:dev\n npm run start:develop\n npm run start:dev:dbg\n npm run start:dev:debug\n npm run start:dev:debug:break\n npm run start:dev:debug:nobreak\n npm run start:watcher:prod\n npm run start:watcher:production\n npm run start:watcher:dev\n npm run start:watcher:develop\n npm run start:watcher:dbg\n npm run start:watcher:debug\n npm run start:watcher:debug:break\n npm run start:watcher:debug:nobreak\n npm run start:watcher:oneshot:prod\n npm run start:watcher:oneshot:production\n npm run start:watcher:oneshot:dev\n npm run start:watcher:oneshot:develop\n npm run start:watcher:oneshot:dbg\n npm run start:watcher:oneshot:debug\n npm run start:watcher:oneshot:debug:break\n npm run start:watcher:oneshot:debug:nobreak\n npm run stop\n npm run stop:watcher\n npm run test\n npm run test:lint\n npm run test:cover\n npm run test:auto:all{:dbg}\n npm run test:auto:version{:dbg}\n npm run test:auto:usertokens{:dbg}\n npm run test:auto:list{:dbg}\n npm run test:auto:resource{:dbg}\n npm run test:auto:policy{:dbg}\n npm run test:auto:role{:dbg}\n npm run test:auto:service{:dbg}\n npm run test:auto:acr{:dbg}\n npm run test:auto:userdata{:dbg}\n npm run test:auto:extdata{:dbg}\n npm run test:auto:watcher{:dbg}\n npm run test:auto:templengine\n npm run test:auto:templengine:async\n npm run test:manual:apis:version_get\n npm run test:manual:apis:usertoken_postput\n npm run test:manual:apis:usertoken_gethead\n npm run test:manual:apis:policy_postput\n npm run test:manual:apis:policy_gethead\n npm run test:manual:apis:policy_delete\n npm run test:manual:apis:resource_postput\n npm run test:manual:apis:resource_gethead\n npm run test:manual:apis:resource_delete\n npm run test:manual:apis:role_postput\n npm run test:manual:apis:role_gethead\n npm run test:manual:apis:role_delete\n npm run test:manual:apis:tenant_postput\n npm run test:manual:apis:tenant_gethead\n npm run test:manual:apis:tenant_delete\n npm run test:manual:apis:service_postput\n npm run test:manual:apis:service_gethead\n npm run test:manual:apis:service_delete\n npm run test:manual:apis:acr_postput\n npm run test:manual:apis:acr_get\n npm run test:manual:apis:acr_delete\n npm run test:manual:apis:list_gethead\n npm run test:manual:apis:userdata_get\n npm run test:manual:apis:extdata_get\n npm run test:manual:apis:allusertenant_get\n npm run test:manual:apis:k2hr3keys_get\n npm run test:manual:load:k2hdkcdata:auto\n npm run test:manual:load:k2hdkcdata:local\n npm run test:manual:templengine\n npm run test:manual:templengine:async\n'",
38
+ "help": "echo 'command list:\n npm run start\n npm run start:prod\n npm run start:production\n npm run start:prod:dbg\n npm run start:prod:debug\n npm run start:prod:debug:break\n npm run start:prod:debug:nobreak\n npm run start:dev\n npm run start:develop\n npm run start:dev:dbg\n npm run start:dev:debug\n npm run start:dev:debug:break\n npm run start:dev:debug:nobreak\n npm run start:watcher:prod\n npm run start:watcher:production\n npm run start:watcher:dev\n npm run start:watcher:develop\n npm run start:watcher:dbg\n npm run start:watcher:debug\n npm run start:watcher:debug:break\n npm run start:watcher:debug:nobreak\n npm run start:watcher:oneshot:prod\n npm run start:watcher:oneshot:production\n npm run start:watcher:oneshot:dev\n npm run start:watcher:oneshot:develop\n npm run start:watcher:oneshot:dbg\n npm run start:watcher:oneshot:debug\n npm run start:watcher:oneshot:debug:break\n npm run start:watcher:oneshot:debug:nobreak\n npm run stop\n npm run stop:watcher\n npm run test\n npm run test:lint\n npm run test:cover\n npm run test:auto:all{:dbg}\n npm run test:auto:version{:dbg}\n npm run test:auto:usertokens{:dbg}\n npm run test:auto:list{:dbg}\n npm run test:auto:resource{:dbg}\n npm run test:auto:policy{:dbg}\n npm run test:auto:role{:dbg}\n npm run test:auto:tenant{:dbg}\n npm run test:auto:service{:dbg}\n npm run test:auto:acr{:dbg}\n npm run test:auto:userdata{:dbg}\n npm run test:auto:extdata{:dbg}\n npm run test:auto:watcher{:dbg}\n npm run test:auto:templengine\n npm run test:auto:templengine:async\n npm run test:manual:apis:version_get\n npm run test:manual:apis:usertoken_postput\n npm run test:manual:apis:usertoken_gethead\n npm run test:manual:apis:policy_postput\n npm run test:manual:apis:policy_gethead\n npm run test:manual:apis:policy_delete\n npm run test:manual:apis:resource_postput\n npm run test:manual:apis:resource_gethead\n npm run test:manual:apis:resource_delete\n npm run test:manual:apis:role_postput\n npm run test:manual:apis:role_gethead\n npm run test:manual:apis:role_delete\n npm run test:manual:apis:tenant_postput\n npm run test:manual:apis:tenant_gethead\n npm run test:manual:apis:tenant_delete\n npm run test:manual:apis:service_postput\n npm run test:manual:apis:service_gethead\n npm run test:manual:apis:service_delete\n npm run test:manual:apis:acr_postput\n npm run test:manual:apis:acr_get\n npm run test:manual:apis:acr_delete\n npm run test:manual:apis:list_gethead\n npm run test:manual:apis:userdata_get\n npm run test:manual:apis:extdata_get\n npm run test:manual:apis:allusertenant_get\n npm run test:manual:apis:k2hr3keys_get\n npm run test:manual:load:k2hdkcdata:auto\n npm run test:manual:load:k2hdkcdata:local\n npm run test:manual:templengine\n npm run test:manual:templengine:async\n'",
39
39
  "start": "npm run start:production",
40
40
  "start:prod": "npm run start:production",
41
41
  "start:production": "bin/run.sh -bg --production && echo '' && echo 'Start on production - Success' && echo ''",
@@ -70,7 +70,7 @@
70
70
  "test": "npm run test:cover",
71
71
  "test:lint": "eslint lib/*.js app.js bin/www bin/watcher routes/*.js tests/*.js",
72
72
  "test:cover": "echo 'Test with coverage' && nyc --reporter=lcov --reporter=text npm run test:auto:all",
73
- "test:auto": "echo 'Auto test : npm run test:auto:*\n test:auto:all{:dbg}\n test:auto:version{:dbg}\n test:auto:usertokens{:dbg}\n test:auto:list{:dbg}\n test:auto:resource{:dbg}\n test:auto:policy{:dbg}\n test:auto:role{:dbg}\n test:auto:tenant{:dbg}\n test:auto:service{:dbg}\n test:auto:acr{:dbg}\n test:auto:userdata{:dbg}\n test:auto:extdata{:dbg}\n test:auto:watcher{:dbg}\n test:auto:templengine\n test:auto:templengine:async\n'",
73
+ "test:auto": "echo 'Auto test : npm run test:auto:*\n test:auto:all{:dbg}\n test:auto:version{:dbg}\n test:auto:usertokens{:dbg}\n test:auto:list{:dbg}\n test:auto:resource{:dbg}\n test:auto:policy{:dbg}\n test:auto:role{:dbg}\n test:auto:tenant{:dbg}\n test:auto:tenant{:dbg}\n test:auto:service{:dbg}\n test:auto:acr{:dbg}\n test:auto:userdata{:dbg}\n test:auto:extdata{:dbg}\n test:auto:watcher{:dbg}\n test:auto:templengine\n test:auto:templengine:async\n'",
74
74
  "test:auto:all": "echo 'All test' && npm run test:lint && tests/test.sh -t 8000 all && npm run test:auto:templengine && npm run test:auto:templengine:async && echo 'Succeed test' && echo ''",
75
75
  "test:auto:all:dbg": "echo 'All test with debugging' && npm run test:lint && tests/test.sh -t 8000 -d dbg all && echo 'Succeed test' && echo ''",
76
76
  "test:auto:version": "echo 'Test Version' && tests/test.sh -t 8000 version && echo 'Succeed test' && echo ''",
package/routes/tenant.js CHANGED
@@ -393,7 +393,23 @@ router.post('/', function(req, res, next) // eslint-disable-line no-unused-v
393
393
  // add own user
394
394
  apiutil.tryAddStringToArray(tenant_users, comparam.user_name);
395
395
  }else{
396
- if(!apiutil.findStringInArray(tenant_users, comparam.user_name)){
396
+ if(apiutil.isEmptyArray(tenant_users)){
397
+ result.result = false;
398
+ result.message = 'POST request tenant(' + tenant_name + ') does not have any user list.';
399
+ r3logger.elog(result.message);
400
+ resutil.errResponse(req, res, 400, result); // 400: Bad Request
401
+ return;
402
+ }
403
+
404
+ var findobj = k2hr3.findTenant(tenant_name, comparam.user_name, tenant_id);
405
+ if( !apiutil.isSafeEntity(findobj) ||
406
+ !apiutil.isSafeEntity(findobj.result) ||
407
+ false === findobj.result ||
408
+ !apiutil.isSafeEntity(findobj.tenant) ||
409
+ !apiutil.isSafeEntity(findobj.tenant.name) ||
410
+ !apiutil.getSafeArray(findobj.tenant.users) ||
411
+ !apiutil.findStringInArray(findobj.tenant.users, comparam.user_name) )
412
+ {
397
413
  result.result = false;
398
414
  result.message = 'POST request tenant(' + tenant_name + ') does not allow user(' + comparam.user_name + ').';
399
415
  r3logger.elog(result.message);
@@ -604,21 +620,37 @@ router.put('/', function(req, res, next) // eslint-disable-line no-unused-va
604
620
  tenant_users = apiutil.parseJSON(req.query.users);
605
621
  if(!apiutil.isArray(tenant_users) && apiutil.isSafeString(tenant_users)){
606
622
  tenant_users = [tenant_users];
607
- }else if(!apiutil.isArray(tenant_users)){
608
- tenant_users = [];
623
+ }else{
624
+ tenant_users = apiutil.getSafeArray(tenant_users);
609
625
  }
610
- }else if(apiutil.isArray(req.query.users)){
611
- tenant_users = req.query.users;
612
- }else if(apiutil.isSafeString(req.query.users)){
626
+ }else if(!apiutil.isArray(req.query.users) && apiutil.isSafeString(req.query.users)){
613
627
  tenant_users = [req.query.users];
614
628
  }else{
615
- tenant_users = [];
629
+ tenant_users = apiutil.getSafeArray(req.query.users);
616
630
  }
631
+
617
632
  if(is_create){
618
633
  // add own user
619
634
  apiutil.tryAddStringToArray(tenant_users, comparam.user_name);
620
635
  }else{
621
- if(!apiutil.findStringInArray(tenant_users, comparam.user_name)){
636
+ // check user in current tenant users
637
+ if(apiutil.isEmptyArray(tenant_users)){
638
+ result.result = false;
639
+ result.message = 'PUT request tenant(' + tenant_name + ') does not have any user list.';
640
+ r3logger.elog(result.message);
641
+ resutil.errResponse(req, res, 400, result); // 400: Bad Request
642
+ return;
643
+ }
644
+
645
+ var findobj = k2hr3.findTenant(tenant_name, comparam.user_name, tenant_id);
646
+ if( !apiutil.isSafeEntity(findobj) ||
647
+ !apiutil.isSafeEntity(findobj.result) ||
648
+ false === findobj.result ||
649
+ !apiutil.isSafeEntity(findobj.tenant) ||
650
+ !apiutil.isSafeEntity(findobj.tenant.name) ||
651
+ !apiutil.getSafeArray(findobj.tenant.users) ||
652
+ !apiutil.findStringInArray(findobj.tenant.users, comparam.user_name) )
653
+ {
622
654
  result.result = false;
623
655
  result.message = 'PUT request tenant(' + tenant_name + ') does not allow user(' + comparam.user_name + ').';
624
656
  r3logger.elog(result.message);
@@ -917,11 +949,26 @@ router.head('/', function(req, res, next)
917
949
  // Router DELETE
918
950
  //=========================================================
919
951
  //
920
- // Mountpath : '/v1/tenant/<tenant>'
952
+ // Mountpath : '/v1/tenant'
921
953
  //
922
- // DELETE '/v1/tenant/<tenant>' : delete tenant on version 1
954
+ //---------------------------------------------------------
955
+ // [DELETE] No tenant path
956
+ //---------------------------------------------------------
957
+ // DELETE '/v1/tenant' : delete tenant version 1
923
958
  // HEADER : X-Auth-Token = <User token>
924
- // url argument : "id": <id> => key is "yrn:yahoo:::<tenant>:id"
959
+ // url argument : "tenant" = <tenant name>
960
+ // url argument : "id" = <id> => key is "yrn:yahoo:::<tenant>:id"
961
+ // response status code : 204 or 4xx/5xx
962
+ // response body : nothing
963
+ //
964
+ // This mount point deletes the specified <K2HR3 cluster LOCAL> tenant.
965
+ //
966
+ //---------------------------------------------------------
967
+ // [DELETE] With tenant path
968
+ //---------------------------------------------------------
969
+ // DELETE '/v1/tenant/tenant' : delete tenant version 1
970
+ // HEADER : X-Auth-Token = <User token>
971
+ // url argument : "id" = <id> => key is "yrn:yahoo:::<tenant>:id"
925
972
  // response status code : 204 or 4xx/5xx
926
973
  // response body : nothing
927
974
  //
@@ -930,7 +977,7 @@ router.head('/', function(req, res, next)
930
977
  // [NOTE]
931
978
  // Only users registered in the tenant to be deleted can delete this tenant.
932
979
  //
933
- router.delete('/', function(req, res, next) // eslint-disable-line no-unused-vars
980
+ router.delete('/', function(req, res, next) // eslint-disable-line no-unused-vars
934
981
  {
935
982
  r3logger.dlog('CALL:', req.method, req.url);
936
983
 
@@ -940,7 +987,7 @@ router.delete('/', function(req, res, next) // eslint-disable-line no-unu
940
987
  !apiutil.isSafeEntity(req.baseUrl) )
941
988
  {
942
989
  r3logger.elog('DELETE request or url or query is wrong');
943
- resutil.errResponse(req, res, 400); // 400: Bad Request
990
+ resutil.errResponse(req, res, 400); // 400: Bad Request
944
991
  return;
945
992
  }
946
993
 
@@ -965,39 +1012,73 @@ router.delete('/', function(req, res, next) // eslint-disable-line no-unu
965
1012
  }
966
1013
 
967
1014
  //------------------------------
968
- // Check uri paths(tenant name)
1015
+ // Check uri paths
969
1016
  //------------------------------
1017
+ var tenant_name;
1018
+ var tenant_id;
970
1019
  if(!apiutil.isSafeString(comparam.tenant_name)){
971
- r3logger.elog('DELETE request tenant must specify <tenant> path');
972
- resutil.errResponse(req, res, 400); // 400: Bad Request
973
- return;
974
- }
1020
+ //------------------------------
1021
+ // Check argments(tenant)
1022
+ //------------------------------
1023
+ tenant_name = apiutil.getSafeString(req.query.tenant);
1024
+ if(!apiutil.isSafeString(tenant_name)){
1025
+ r3logger.elog('DELETE request tenant must specify in argument');
1026
+ resutil.errResponse(req, res, 400); // 400: Bad Request
1027
+ return;
1028
+ }
975
1029
 
976
- //------------------------------
977
- // Check argments(id)
978
- //------------------------------
979
- var tenant_id = apiutil.getSafeString(req.query.id);
980
- if(!apiutil.isSafeString(tenant_id)){
981
- r3logger.elog('DELETE request id must specify in argument');
982
- resutil.errResponse(req, res, 400); // 400: Bad Request
983
- return;
984
- }
1030
+ //------------------------------
1031
+ // Check argments(id)
1032
+ //------------------------------
1033
+ tenant_id = apiutil.getSafeString(req.query.id);
1034
+ if(!apiutil.isSafeString(tenant_id)){
1035
+ r3logger.elog('DELETE request id must specify in argument');
1036
+ resutil.errResponse(req, res, 400); // 400: Bad Request
1037
+ return;
1038
+ }
985
1039
 
986
- //------------------------------
987
- // Processing
988
- //------------------------------
989
- resobj = k2hr3.removeUserFromLocalTenant(comparam.tenant_name, comparam.user_name, tenant_id);
990
- if(!apiutil.isSafeEntity(resobj) || !apiutil.isSafeEntity(resobj.result) || false === resobj.result){
991
- if(apiutil.isSafeEntity(resobj) && apiutil.isSafeString(resobj.message)){
992
- r3logger.elog('DELETE request failed to remove user from tenant by ' + resobj.message);
993
- }else{
994
- r3logger.elog('DELETE request failed to remove user from tenant by unknown reason');
1040
+ //------------------------------
1041
+ // Processing
1042
+ //------------------------------
1043
+ resobj = k2hr3.removeLocalTenant(tenant_name, comparam.user_name, tenant_id);
1044
+ if(!apiutil.isSafeEntity(resobj) || !apiutil.isSafeEntity(resobj.result) || false === resobj.result){
1045
+ if(apiutil.isSafeEntity(resobj) && apiutil.isSafeString(resobj.message)){
1046
+ r3logger.elog('DELETE request failed to remove user from tenant by ' + resobj.message);
1047
+ }else{
1048
+ r3logger.elog('DELETE request failed to remove user from tenant by unknown reason');
1049
+ }
1050
+ resutil.errResponse(req, res, 400); // 400: Bad Request
1051
+ return;
995
1052
  }
996
- resutil.errResponse(req, res, 400); // 400: Bad Request
997
- return;
1053
+ r3logger.dlog('DELETE request succeed - remove tenant');
1054
+
1055
+ }else{
1056
+ //------------------------------
1057
+ // Check argments(id)
1058
+ //------------------------------
1059
+ tenant_id = apiutil.getSafeString(req.query.id);
1060
+ if(!apiutil.isSafeString(tenant_id)){
1061
+ r3logger.elog('DELETE request id must specify in argument');
1062
+ resutil.errResponse(req, res, 400); // 400: Bad Request
1063
+ return;
1064
+ }
1065
+
1066
+ //------------------------------
1067
+ // Processing
1068
+ //------------------------------
1069
+ resobj = k2hr3.removeUserFromLocalTenant(comparam.tenant_name, comparam.user_name, tenant_id);
1070
+ if(!apiutil.isSafeEntity(resobj) || !apiutil.isSafeEntity(resobj.result) || false === resobj.result){
1071
+ if(apiutil.isSafeEntity(resobj) && apiutil.isSafeString(resobj.message)){
1072
+ r3logger.elog('DELETE request failed to remove user from tenant by ' + resobj.message);
1073
+ }else{
1074
+ r3logger.elog('DELETE request failed to remove user from tenant by unknown reason');
1075
+ }
1076
+ resutil.errResponse(req, res, 400); // 400: Bad Request
1077
+ return;
1078
+ }
1079
+ r3logger.dlog('DELETE request succeed - remove user from tenant');
998
1080
  }
999
1081
 
1000
- r3logger.dlog('DELETE request succeed - remove user from tenant');
1001
1082
  res.status(204); // 204: No Content
1002
1083
  res.send();
1003
1084
  });
@@ -604,8 +604,7 @@ describe('API : TENANT', function(){ // eslint-disable-line no-undef
604
604
  expect(res).to.be.json;
605
605
  expect(res.body).to.be.an('object');
606
606
  expect(res.body.result).to.be.a('boolean').to.be.false;
607
- expect(res.body.message).to.be.a('string').to.have.string('PUT request failed to update tenant by failed to update tenant by could not find tenant(local@autotest_put_tenant_3) with user="dummyuser" and id=');
608
-
607
+ expect(res.body.message).to.be.a('string').to.have.string('PUT request tenant(local@autotest_put_tenant_3) does not allow user(dummyuser).');
609
608
  done();
610
609
  });
611
610
  });
@@ -904,9 +903,9 @@ describe('API : TENANT', function(){ // eslint-disable-line no-undef
904
903
  });
905
904
 
906
905
  //
907
- // Run Test(DELETE - TENANT - SUCCESS/FAILURE)
906
+ // Run Test(DELETE - TENANT USER - SUCCESS/FAILURE)
908
907
  //
909
- it('DELETE /v1/tenant/<tenant> : delete tenant(autotest_put_tenant_0) : success 200', function(done){ // eslint-disable-line no-undef
908
+ it('DELETE /v1/tenant/<tenant> : delete tenant user(autotest_put_tenant_0) : success 204', function(done){ // eslint-disable-line no-undef
910
909
  var uri = '/v1/tenant/autotest_put_tenant_0'; // tenant name
911
910
  uri += '?id=' + autotest_put_tenant_0_id; // correct id
912
911
 
@@ -921,7 +920,7 @@ describe('API : TENANT', function(){ // eslint-disable-line no-undef
921
920
  });
922
921
  });
923
922
 
924
- it('DELETE /v1/tenant/<tenant> : delete tenant(local@autotest_put_tenant_1) : success 200', function(done){ // eslint-disable-line no-undef
923
+ it('DELETE /v1/tenant/<tenant> : delete tenant user(local@autotest_put_tenant_1) : success 204', function(done){ // eslint-disable-line no-undef
925
924
  var uri = '/v1/tenant/local@autotest_put_tenant_1'; // tenant name
926
925
  uri += '?id=' + autotest_put_tenant_1_id; // correct id
927
926
 
@@ -936,7 +935,7 @@ describe('API : TENANT', function(){ // eslint-disable-line no-undef
936
935
  });
937
936
  });
938
937
 
939
- it('DELETE /v1/tenant/<tenant> : delete tenant(autotest_post_tenant_0) : failure(no token) 400', function(done){ // eslint-disable-line no-undef
938
+ it('DELETE /v1/tenant/<tenant> : delete tenant user(autotest_post_tenant_0) : failure(no token) 400', function(done){ // eslint-disable-line no-undef
940
939
  var uri = '/v1/tenant/autotest_post_tenant_0'; // tenant name
941
940
  uri += '?id=' + autotest_post_tenant_0_id; // correct id
942
941
 
@@ -950,7 +949,7 @@ describe('API : TENANT', function(){ // eslint-disable-line no-undef
950
949
  });
951
950
  });
952
951
 
953
- it('DELETE /v1/tenant/<tenant> : delete tenant(local@autotest_post_tenant_0) : failure(no token) 400', function(done){ // eslint-disable-line no-undef
952
+ it('DELETE /v1/tenant/<tenant> : delete tenant user(local@autotest_post_tenant_0) : failure(no token) 400', function(done){ // eslint-disable-line no-undef
954
953
  var uri = '/v1/tenant/local@autotest_post_tenant_0'; // tenant name
955
954
  uri += '?id=' + autotest_post_tenant_0_id; // correct id
956
955
 
@@ -964,7 +963,7 @@ describe('API : TENANT', function(){ // eslint-disable-line no-undef
964
963
  });
965
964
  });
966
965
 
967
- it('DELETE /v1/tenant/<tenant> : delete tenant(autotest_post_tenant_X) : failure(no exist tenant) 400', function(done){ // eslint-disable-line no-undef
966
+ it('DELETE /v1/tenant/<tenant> : delete tenant user(autotest_post_tenant_X) : failure(no exist tenant) 400', function(done){ // eslint-disable-line no-undef
968
967
  var uri = '/v1/tenant/autotest_post_tenant_X'; // not exist tenant name
969
968
  uri += '?id=' + autotest_post_tenant_0_id; // wrong id
970
969
 
@@ -977,6 +976,118 @@ describe('API : TENANT', function(){ // eslint-disable-line no-undef
977
976
  done();
978
977
  });
979
978
  });
979
+
980
+ //
981
+ // Run Test(DELETE - TENANT - SUCCESS/FAILURE)
982
+ //
983
+ it('DELETE /v1/tenant : delete tenant(autotest_post_tenant_0) : failure(no token) 400', function(done){ // eslint-disable-line no-undef
984
+ var uri = '/v1/tenant';
985
+ uri += '?tenant=autotest_post_tenant_0'; // tenant name
986
+ uri += '&id=' + autotest_post_tenant_0_id; // correct id
987
+
988
+ chai.request(app)
989
+ .delete(uri)
990
+ .set('content-type', 'application/json')
991
+ .end(function(err, res){
992
+ expect(res).to.have.status(400);
993
+
994
+ done();
995
+ });
996
+ });
997
+
998
+ it('DELETE /v1/tenant : delete tenant(local@autotest_post_tenant_0) : failure(no tenant) 400', function(done){ // eslint-disable-line no-undef
999
+ var uri = '/v1/tenant';
1000
+ uri += '?id=' + autotest_post_tenant_0_id; // correct id
1001
+
1002
+ chai.request(app)
1003
+ .delete(uri)
1004
+ .set('content-type', 'application/json')
1005
+ .set('x-auth-token', alltokens.unscopedtoken) // unscoped token
1006
+ .end(function(err, res){
1007
+ expect(res).to.have.status(400);
1008
+
1009
+ done();
1010
+ });
1011
+ });
1012
+
1013
+ it('DELETE /v1/tenant : delete tenant(local@autotest_post_tenant_0) : failure(no id) 400', function(done){ // eslint-disable-line no-undef
1014
+ var uri = '/v1/tenant';
1015
+ uri += '?tenant=autotest_post_tenant_0'; // tenant name
1016
+
1017
+ chai.request(app)
1018
+ .delete(uri)
1019
+ .set('content-type', 'application/json')
1020
+ .set('x-auth-token', alltokens.unscopedtoken) // unscoped token
1021
+ .end(function(err, res){
1022
+ expect(res).to.have.status(400);
1023
+
1024
+ done();
1025
+ });
1026
+ });
1027
+
1028
+ it('DELETE /v1/tenant : delete tenant(autotest_post_tenant_X) : failure(no exist tenant) 400', function(done){ // eslint-disable-line no-undef
1029
+ var uri = '/v1/tenant';
1030
+ uri += '?tenant=autotest_post_tenant_X'; // not exist tenant name
1031
+ uri += '&id=' + autotest_post_tenant_0_id; // id
1032
+
1033
+ chai.request(app)
1034
+ .delete(uri)
1035
+ .set('content-type', 'application/json')
1036
+ .set('x-auth-token', alltokens.unscopedtoken) // unscoped token
1037
+ .end(function(err, res){
1038
+ expect(res).to.have.status(400);
1039
+
1040
+ done();
1041
+ });
1042
+ });
1043
+
1044
+ it('DELETE /v1/tenant : delete tenant(autotest_post_tenant_X) : failure(wrong id) 400', function(done){ // eslint-disable-line no-undef
1045
+ var uri = '/v1/tenant';
1046
+ uri += '?tenant=autotest_post_tenant_0'; // tenant name
1047
+ uri += '&id=' + autotest_post_tenant_1_id; // wrong id
1048
+
1049
+ chai.request(app)
1050
+ .delete(uri)
1051
+ .set('content-type', 'application/json')
1052
+ .set('x-auth-token', alltokens.unscopedtoken) // unscoped token
1053
+ .end(function(err, res){
1054
+ expect(res).to.have.status(400);
1055
+
1056
+ done();
1057
+ });
1058
+ });
1059
+
1060
+ it('DELETE /v1/tenant : delete tenant(autotest_post_tenant_0) : failure(not local@) 400', function(done){ // eslint-disable-line no-undef
1061
+ var uri = '/v1/tenant';
1062
+ uri += '?tenant=autotest_post_tenant_0'; // tenant name
1063
+ uri += '&id=' + autotest_post_tenant_0_id; // correct id
1064
+
1065
+ chai.request(app)
1066
+ .delete(uri)
1067
+ .set('content-type', 'application/json')
1068
+ .set('x-auth-token', alltokens.unscopedtoken) // unscoped token
1069
+ .end(function(err, res){
1070
+ expect(res).to.have.status(400);
1071
+
1072
+ done();
1073
+ });
1074
+ });
1075
+
1076
+ it('DELETE /v1/tenant/<tenant> : delete tenant(local@autotest_post_tenant_1) : success 204', function(done){ // eslint-disable-line no-undef
1077
+ var uri = '/v1/tenant';
1078
+ uri += '?tenant=local@autotest_post_tenant_1'; // tenant name
1079
+ uri += '&id=' + autotest_post_tenant_1_id; // correct id
1080
+
1081
+ chai.request(app)
1082
+ .delete(uri)
1083
+ .set('content-type', 'application/json')
1084
+ .set('x-auth-token', alltokens.unscopedtoken) // unscoped token
1085
+ .end(function(err, res){
1086
+ expect(res).to.have.status(204);
1087
+
1088
+ done();
1089
+ });
1090
+ });
980
1091
  });
981
1092
 
982
1093
  /*
@@ -40,20 +40,32 @@ var is_https = apiutil.compareCaseString('yes', process.env.HTTPS_ENV);
40
40
  //
41
41
  // Request API for test
42
42
  //
43
- function deleteV1Tenant(token, name, id)
43
+ function deleteV1Tenant(token, name, id, remove_all)
44
44
  {
45
45
  var headers = {
46
46
  'Content-Type': 'application/json',
47
47
  'Content-Length': 0,
48
48
  'X-Auth-Token': token
49
49
  };
50
- var options = {
51
- 'host': hostname,
52
- 'port': hostport,
53
- 'path': '/v1/tenant/' + name + encodeURI('?id=' + id),
54
- 'method': 'DELETE',
55
- 'headers': headers
56
- };
50
+
51
+ var options;
52
+ if(remove_all){
53
+ options = {
54
+ 'host': hostname,
55
+ 'port': hostport,
56
+ 'path': '/v1/tenant' + encodeURI('?tenant=' + name) + '&' + encodeURI('id=' + id),
57
+ 'method': 'DELETE',
58
+ 'headers': headers
59
+ };
60
+ }else{
61
+ options = {
62
+ 'host': hostname,
63
+ 'port': hostport,
64
+ 'path': '/v1/tenant/' + name + encodeURI('?id=' + id),
65
+ 'method': 'DELETE',
66
+ 'headers': headers
67
+ };
68
+ }
57
69
 
58
70
  r3logger.dlog('request options = ' + JSON.stringify(options));
59
71
  r3logger.dlog('request headers = ' + JSON.stringify(headers));
@@ -134,10 +146,32 @@ cliutil.getConsoleInput('Unscoped(or Scoped) user token : ', true, false,
134
146
  }
135
147
  var _id = apiutil.getSafeString(id);
136
148
 
137
- //
138
- // Run
139
- //
140
- deleteV1Tenant(_token, _tenant, _id);
149
+ cliutil.getConsoleInput('Remove tenant(yes/no(default)) : ', true, false, function(isbreak, remove_all)
150
+ {
151
+ if(isbreak){
152
+ process.exit(0);
153
+ }
154
+
155
+ var _remove_all;
156
+ if(!apiutil.isSafeString(remove_all) || 'no' == remove_all || 'n' == remove_all){
157
+ _remove_all = false;
158
+ }else if('yes' == remove_all || 'y' == remove_all){
159
+ _remove_all = true;
160
+
161
+ if(0 !== _tenant.indexOf('local@')){
162
+ console.log('Need tenant name started with local@ for remove it.');
163
+ process.exit(0);
164
+ }
165
+ }else{
166
+ console.log('input must be yes or no(null)');
167
+ process.exit(0);
168
+ }
169
+
170
+ //
171
+ // Run
172
+ //
173
+ deleteV1Tenant(_token, _tenant, _id, _remove_all);
174
+ });
141
175
  });
142
176
  });
143
177
  });