k2hr3-api 1.0.24 → 1.0.26

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.
Files changed (42) hide show
  1. package/ChangeLog +12 -0
  2. package/app.js +63 -30
  3. package/bin/run.sh +14 -0
  4. package/config/default.json +3 -2
  5. package/lib/k2hr3config.js +12 -0
  6. package/lib/k2hr3dkc.js +903 -13
  7. package/lib/k2hr3keys.js +1 -0
  8. package/lib/k2hr3tokens.js +147 -60
  9. package/package.json +10 -5
  10. package/routes/tenant.js +1014 -0
  11. package/routes/userTokens.js +77 -126
  12. package/tests/auto_all_spec.js +4 -0
  13. package/tests/auto_tenant.js +989 -0
  14. package/tests/auto_tenant_spec.js +79 -0
  15. package/tests/auto_usertokens.js +6 -6
  16. package/tests/manual_acr_delete.js +1 -0
  17. package/tests/manual_acr_get.js +1 -0
  18. package/tests/manual_acr_postput.js +1 -0
  19. package/tests/manual_allusertenant_get.js +58 -3
  20. package/tests/manual_extdata_get.js +1 -0
  21. package/tests/manual_list_gethead.js +1 -0
  22. package/tests/manual_policy_delete.js +1 -0
  23. package/tests/manual_policy_gethead.js +3 -1
  24. package/tests/manual_policy_postput.js +1 -0
  25. package/tests/manual_resource_delete.js +1 -0
  26. package/tests/manual_resource_gethead.js +1 -0
  27. package/tests/manual_resource_postput.js +1 -0
  28. package/tests/manual_role_delete.js +2 -0
  29. package/tests/manual_role_gethead.js +4 -0
  30. package/tests/manual_role_postput.js +2 -0
  31. package/tests/manual_service_delete.js +1 -0
  32. package/tests/manual_service_gethead.js +1 -0
  33. package/tests/manual_service_postput.js +1 -0
  34. package/tests/manual_tenant_delete.js +152 -0
  35. package/tests/manual_tenant_gethead.js +268 -0
  36. package/tests/manual_tenant_postput.js +293 -0
  37. package/tests/manual_test.sh +21 -7
  38. package/tests/manual_userdata_get.js +1 -0
  39. package/tests/manual_usertoken_gethead.js +1 -0
  40. package/tests/manual_usertoken_postput.js +1 -0
  41. package/tests/manual_version_get.js +1 -0
  42. package/tests/test.sh +2 -0
package/lib/k2hr3dkc.js CHANGED
@@ -1550,21 +1550,851 @@ function rawCheckTenantInServiceMember(servicename, tenantname)
1550
1550
  }
1551
1551
 
1552
1552
  //---------------------------------------------------------
1553
- // Common raw create tenant key
1553
+ // Common raw find tenant key
1554
+ //---------------------------------------------------------
1555
+ // tenant : tenant name
1556
+ // user : user name
1557
+ // id : tenant id (if user is specified, need this.)
1558
+ //
1559
+ // result : null is not found
1560
+ // tenant object is found:
1561
+ // {
1562
+ // name: <name>
1563
+ // id: <id>
1564
+ // desc: <description>
1565
+ // display: <display tenant name>
1566
+ // users: [user, ...] <-- "user name"(not yrn path)
1567
+ // }
1568
+ //
1569
+ // [NOTE]
1570
+ // If user and id are not specified, all tenants will be searched.
1571
+ // If user and id are specified, it will be searched by those exact matches.
1572
+ //
1573
+ function rawFindTenantEx(dkcobj_permanent, tenant, user, id)
1574
+ {
1575
+ if(!(dkcobj_permanent instanceof Object) || !dkcobj_permanent.isPermanent()){
1576
+ r3logger.elog('parameter dkcobj_permanent is not object or not permanent');
1577
+ return null;
1578
+ }
1579
+ if(!apiutil.isSafeString(tenant)){ // allow user and id are null
1580
+ r3logger.elog('some parameters are wrong : tenant=' + JSON.stringify(tenant));
1581
+ return null;
1582
+ }
1583
+ if(apiutil.isSafeString(user) != apiutil.isSafeString(id)){ // allow both user and id are empty or not empty
1584
+ r3logger.elog('some parameters are wrong : tenant=' + JSON.stringify(tenant) + ', user=' + JSON.stringify(user) + ', id=' + JSON.stringify(id));
1585
+ return null;
1586
+ }
1587
+ tenant = apiutil.getSafeString(tenant);
1588
+ user = apiutil.getSafeString(user);
1589
+ id = apiutil.getSafeString(id);
1590
+
1591
+ //
1592
+ // Keys
1593
+ //
1594
+ var keys = r3keys(user, tenant);
1595
+
1596
+ //
1597
+ // Check tenant
1598
+ //
1599
+ var tenantval = dkcobj_permanent.getValue(keys.MASTER_TENANT_TOP_KEY, null, true, null); // get value in yrn:yahoo:::<tenant>
1600
+ if(!apiutil.isSafeString(tenantval) || tenantval != keys.VALUE_ENABLE){
1601
+ r3logger.dlog('not found tenant(' + tenant + ') or its value is not ' + keys.VALUE_ENABLE + '.');
1602
+ return null;
1603
+ }
1604
+
1605
+ var subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.NO_SERVICE_REGION_KEY, true));
1606
+ if(!apiutil.findStringInArray(subkeylist, keys.MASTER_TENANT_TOP_KEY)){ // check subkey yrn:yahoo:::<tenant> -> yrn:yahoo::
1607
+ r3logger.dlog('not found tenant(' + tenant + ') under ' + keys.NO_SERVICE_REGION_KEY + ' key.');
1608
+ return null;
1609
+ }
1610
+
1611
+ //
1612
+ // Get tenant information
1613
+ //
1614
+ var id_value = dkcobj_permanent.getValue(keys.TENANT_ID_KEY, null, true, null);
1615
+ var desc_value = dkcobj_permanent.getValue(keys.TENANT_DESC_KEY, null, true, null);
1616
+ var display_value = dkcobj_permanent.getValue(keys.TENANT_DISP_KEY, null, true, null);
1617
+ var userlist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.TENANT_USER_KEY, true));
1618
+
1619
+ //
1620
+ // Check id and user
1621
+ //
1622
+ if(apiutil.isSafeString(id) && apiutil.isSafeString(user)){
1623
+ //
1624
+ // Check id value
1625
+ //
1626
+ if(id_value != id){
1627
+ r3logger.elog('Tenant(' + tenant + ') id(' + id_value + ') is not as same as id(' + id + ')');
1628
+ return null;
1629
+ }
1630
+ //
1631
+ // Check user in list
1632
+ //
1633
+ if(!apiutil.findStringInArray(userlist, keys.USER_KEY)){
1634
+ r3logger.elog('Tenant(' + tenant + ') does not have user(' + user + ')');
1635
+ return null;
1636
+ }
1637
+ }
1638
+
1639
+ //
1640
+ // Make result user list
1641
+ //
1642
+ var username_list = Array();
1643
+ for(var cnt = 0; cnt < userlist.length; ++cnt){
1644
+ var tmpuser = apiutil.getSafeString(userlist[cnt]);
1645
+ if(0 !== tmpuser.indexOf(keys.USER_TOP_KEY + ':')){
1646
+ r3logger.wlog('Tenant(' + tenant + ') has unknown formatted user value(' + tmpuser + ')');
1647
+ continue;
1648
+ }
1649
+ // cut yrn path
1650
+ tmpuser = tmpuser.replace(keys.USER_TOP_KEY + ':', '');
1651
+
1652
+ // add
1653
+ apiutil.tryAddStringToArray(username_list, tmpuser);
1654
+ }
1655
+ username_list.sort();
1656
+
1657
+ //
1658
+ // result object
1659
+ //
1660
+ var resobj = {
1661
+ name: tenant,
1662
+ id: id_value,
1663
+ desc: desc_value,
1664
+ display: display_value,
1665
+ users: username_list
1666
+ };
1667
+
1668
+ return resobj;
1669
+ }
1670
+
1671
+ //
1672
+ // tenant : tenant name
1673
+ // user : user name
1674
+ // id : tenant id, if user is specified(service is specified, do not need this)
1675
+ //
1676
+ // result {
1677
+ // result: true/false
1678
+ // message: null or error message
1679
+ // tenant: undefined or object
1680
+ // {
1681
+ // name: <name>
1682
+ // id: <id>
1683
+ // desc: <description>
1684
+ // display: <display tenant name>
1685
+ // users: [user, ...] <-- "user name"(not yrn path)
1686
+ // }
1687
+ // }
1688
+ //
1689
+ // [NOTE]
1690
+ // If user and id are not specified, all tenants will be searched.
1691
+ // If user and id are specified, it will be searched by those exact matches.
1692
+ //
1693
+ function rawFindTenant(tenant, user, id)
1694
+ {
1695
+ var resobj = {result: true, message: null};
1696
+
1697
+ if(!apiutil.isSafeStrings(tenant)){ // allow user and id are null
1698
+ resobj.result = false;
1699
+ resobj.message = 'some parameters are wrong : tenant=' + JSON.stringify(tenant);
1700
+ r3logger.elog(resobj.message);
1701
+ return resobj;
1702
+ }
1703
+ if(apiutil.isSafeString(user) != apiutil.isSafeString(id)){ // allow both user and id are empty or not empty
1704
+ resobj.result = false;
1705
+ resobj.message = 'some parameters are wrong : tenant=' + JSON.stringify(tenant) + ', user=' + JSON.stringify(user) + ', id=' + JSON.stringify(id);
1706
+ r3logger.elog(resobj.message);
1707
+ return resobj;
1708
+ }
1709
+
1710
+ var dkcobj = k2hdkc(dkcconf, dkcport, dkccuk, true, false); // use permanent object(need to clean)
1711
+ if(!rawInitKeyHierarchy(dkcobj)){
1712
+ resobj.result = false;
1713
+ resobj.message = 'Not initialize yet, or configuration is not set';
1714
+ r3logger.elog(resobj.message);
1715
+ dkcobj.clean();
1716
+ return resobj;
1717
+ }
1718
+
1719
+ //
1720
+ // Find tenant
1721
+ //
1722
+ var result = rawFindTenantEx(dkcobj, tenant, user, id);
1723
+ if(!apiutil.isSafeEntity(result)){
1724
+ resobj.result = false;
1725
+ resobj.message = 'could not find tenant(' + tenant + ') with user=' + JSON.stringify(user) + ' and id=' + JSON.stringify(id);
1726
+ r3logger.elog(resobj.message);
1727
+ dkcobj.clean();
1728
+ return resobj;
1729
+ }
1730
+ dkcobj.clean();
1731
+
1732
+ //
1733
+ // Set found tenant object
1734
+ //
1735
+ resobj.tenant = result;
1736
+
1737
+ return resobj;
1738
+ }
1739
+
1740
+ //---------------------------------------------------------
1741
+ // Common raw list local tenant
1742
+ //---------------------------------------------------------
1743
+ //
1744
+ // user : user name
1745
+ //
1746
+ // result : null is not found
1747
+ // tenant object is found:
1748
+ // {
1749
+ // name: <name>
1750
+ // id: <id>
1751
+ // desc: <description>
1752
+ // display: <display tenant name>
1753
+ // users: [user, ...] <-- "user name"(not yrn path)
1754
+ // }
1755
+ //
1756
+ function rawGetLocalTenantList(dkcobj_permanent, user)
1757
+ {
1758
+ if(!(dkcobj_permanent instanceof Object) || !dkcobj_permanent.isPermanent()){
1759
+ r3logger.elog('parameter dkcobj_permanent is not object or not permanent');
1760
+ return null;
1761
+ }
1762
+ if(!apiutil.isSafeString(user)){ // allow user and id are null
1763
+ r3logger.elog('some parameters are wrong : tenant=' + JSON.stringify(tenant));
1764
+ return null;
1765
+ }
1766
+
1767
+ //
1768
+ // Keys
1769
+ //
1770
+ var keys = r3keys(user);
1771
+
1772
+ //
1773
+ // Loop: tenant key
1774
+ //
1775
+ var tenants = [];
1776
+ var subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.NO_SERVICE_REGION_KEY, true));
1777
+ for(var cnt = 0; cnt < subkeylist.length; ++cnt){
1778
+ // tenant path
1779
+ var tenant = apiutil.getSafeString(subkeylist[cnt]); // tenant => "yrn:yahoo:::<tenant>"
1780
+
1781
+ // check
1782
+ if(0 !== tenant.indexOf(keys.NO_SERVICE_TENANT_KEY)){
1783
+ r3logger.wlog('Tenant yrn path (' + tenant + ') is unknown format, skip it...');
1784
+ continue;
1785
+ }
1786
+ if(tenant === keys.NO_SERVICE_TENANT_KEY){ // tenant => "yrn:yahoo:::"
1787
+ continue;
1788
+ }
1789
+
1790
+ // cut yrn path
1791
+ var tenant_name = tenant.replace(keys.USER_TENANT_COMMON_KEY, '');
1792
+
1793
+ // check local tenant
1794
+ if(0 !== tenant_name.indexOf(keys.VALUE_PREFIX_LOCAL_TENANT)){
1795
+ continue;
1796
+ }
1797
+
1798
+ // change keys
1799
+ keys = r3keys(user, tenant_name);
1800
+
1801
+ //
1802
+ // Get tenant information
1803
+ //
1804
+ var id_value = dkcobj_permanent.getValue(keys.TENANT_ID_KEY, null, true, null);
1805
+ var desc_value = dkcobj_permanent.getValue(keys.TENANT_DESC_KEY, null, true, null);
1806
+ var display_value = dkcobj_permanent.getValue(keys.TENANT_DISP_KEY, null, true, null);
1807
+ var userlist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.TENANT_USER_KEY, true));
1808
+
1809
+ //
1810
+ // Check id value
1811
+ //
1812
+ if(!apiutil.isSafeString(id_value)){
1813
+ r3logger.wlog('Tenant yrn path (' + tenant + ') has wrong id value, skip it...');
1814
+ continue;
1815
+ }
1816
+
1817
+ //
1818
+ // Check user in list
1819
+ //
1820
+ if(!apiutil.findStringInArray(userlist, keys.TENANT_USER_KEY)){
1821
+ r3logger.dlog('User(' + user + ') is not Tenant(' + tenant + ') member, skip it.');
1822
+ return null;
1823
+ }
1824
+
1825
+ //
1826
+ // Make result user list
1827
+ //
1828
+ var username_list = Array();
1829
+ for(var cnt2 = 0; cnt2 < userlist.length; ++cnt2){
1830
+ var tmpuser = apiutil.getSafeString(userlist[cnt2]);
1831
+ if(0 !== tmpuser.indexOf(keys.USER_TOP_KEY + ':')){
1832
+ r3logger.wlog('Tenant(' + tenant_name + ') has unknown formatted user value(' + tmpuser + ')');
1833
+ continue;
1834
+ }
1835
+ // cut yrn path
1836
+ tmpuser = tmpuser.replace(keys.USER_TOP_KEY + ':', '');
1837
+
1838
+ // add
1839
+ apiutil.tryAddStringToArray(username_list, tmpuser);
1840
+ }
1841
+ username_list.sort();
1842
+
1843
+ //
1844
+ // add tenant object
1845
+ //
1846
+ tenants.push({
1847
+ name: tenant_name,
1848
+ id: id_value,
1849
+ desc: desc_value,
1850
+ display: display_value,
1851
+ users: username_list
1852
+ });
1853
+ }
1854
+
1855
+ return tenants;
1856
+ }
1857
+
1858
+ //
1859
+ // user : user name
1860
+ // is_expand : expand tenant object
1861
+ //
1862
+ // result {
1863
+ // result: true/false
1864
+ // message: null or error message
1865
+ // tenants: undefined or object array
1866
+ // [
1867
+ // "tenant name",
1868
+ // ...
1869
+ // ]
1870
+ // or
1871
+ // [
1872
+ // {
1873
+ // name: <name>
1874
+ // id: <id>
1875
+ // desc: <description>
1876
+ // display: <display tenant name>
1877
+ // users: [user, ...] <-- "user name"(not yrn path)
1878
+ // },
1879
+ // ]
1880
+ // }
1881
+ //
1882
+ // [NOTE]
1883
+ // If find an unnecessary tenant key, update it.
1884
+ //
1885
+ function rawListLocalTenant(user, is_expand)
1886
+ {
1887
+ var resobj = {result: true, message: null};
1888
+
1889
+ if('boolean' !== typeof is_expand){
1890
+ is_expand = false; // default not expand
1891
+ }
1892
+
1893
+ if(!apiutil.isSafeString(user)){
1894
+ resobj.result = false;
1895
+ resobj.message = 'some parameters are wrong : user=' + JSON.stringify(user);
1896
+ r3logger.elog(resobj.message);
1897
+ return resobj;
1898
+ }
1899
+
1900
+ var dkcobj = k2hdkc(dkcconf, dkcport, dkccuk, true, false); // use permanent object(need to clean)
1901
+ if(!rawInitKeyHierarchy(dkcobj)){
1902
+ resobj.result = false;
1903
+ resobj.message = 'Not initialize yet, or configuration is not set';
1904
+ r3logger.elog(resobj.message);
1905
+ dkcobj.clean();
1906
+ return resobj;
1907
+ }
1908
+
1909
+ //
1910
+ // Keys
1911
+ //
1912
+ var keys = r3keys(user);
1913
+
1914
+ //
1915
+ // Check all local tenant list for user (if not existed, add it)
1916
+ //
1917
+ var localtenantlist = apiutil.getSafeArray(rawGetLocalTenantList(dkcobj, user));
1918
+ var usertenantlist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.USER_TENANT_TOP_KEY, true));
1919
+ var need_update = false;
1920
+ for(var cnt = 0; cnt < localtenantlist.length; ++cnt){
1921
+ // tmpkeys
1922
+ var tmpkeys = r3keys(user, localtenantlist[cnt].name);
1923
+
1924
+ // check
1925
+ if(!apiutil.findStringInArray(usertenantlist, tmpkeys.USER_TENANT_KEY)){
1926
+ r3logger.dlog('user(' + user + ') does not have local tenant(' + localtenantlist[cnt].name + '), so add it.');
1927
+ usertenantlist.push(tmpkeys.USER_TENANT_KEY);
1928
+ need_update = true; // for add local tenant
1929
+ }
1930
+ }
1931
+ if(need_update){
1932
+ if(!dkcobj.setSubkeys(keys.USER_TENANT_TOP_KEY, usertenantlist)){ // Update subkey "yrn:yahoo::::user:<user>:tenant"
1933
+ r3logger.elog('could not update (' + keys.USER_TENANT_TOP_KEY + ') subkey, but continue...');
1934
+ }
1935
+ }
1936
+
1937
+ //
1938
+ // Make list from tenant list in users
1939
+ //
1940
+ var tenants = [];
1941
+ var subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.USER_TENANT_TOP_KEY, true));
1942
+ var update_list = [];
1943
+ need_update = false;
1944
+ for(cnt = 0; cnt < subkeylist.length; ++cnt){
1945
+ var tenant_name = apiutil.getSafeString(subkeylist[cnt]); // tenant_name => "yrn:yahoo::::user:<user>:tenant/" or "yrn:yahoo::::user:<user>:tenant/<name>"
1946
+
1947
+ if(0 !== tenant_name.indexOf(keys.USER_TENANT_COMMON_KEY)){
1948
+ r3logger.wlog('Tenant yrn path (' + tenant_name + ') in user(' + user + ') is unknown format, remove this subkey...');
1949
+ need_update = true; // for cut this invalid subkey
1950
+ continue;
1951
+ }
1952
+
1953
+ // cut yrn path
1954
+ tenant_name = tenant_name.replace(keys.USER_TENANT_COMMON_KEY, '');
1955
+ if(!apiutil.isSafeString(tenant_name)){ // tenant key is "yrn:yahoo::::user:<user>:tenant/"
1956
+ apiutil.tryAddStringToArray(update_list, subkeylist[cnt]); // set subkey list(if update it)
1957
+ continue;
1958
+ }
1959
+
1960
+ // check local tenant
1961
+ if(0 !== tenant_name.indexOf(keys.VALUE_PREFIX_LOCAL_TENANT)){
1962
+ apiutil.tryAddStringToArray(update_list, subkeylist[cnt]); // set subkey list(if update it)
1963
+ continue;
1964
+ }
1965
+
1966
+ // get tenant object
1967
+ var tenant_obj = rawFindTenantEx(dkcobj, tenant_name);
1968
+ if(!apiutil.isSafeEntity(tenant_obj)){
1969
+ r3logger.wlog('could not get tenant object for tenant(' + tenant_name + ') in user(' + user + '), remove this subkey...');
1970
+ need_update = true; // for cut this invalid subkey
1971
+ continue;
1972
+ }
1973
+
1974
+ // check user in list
1975
+ if(!apiutil.findStringInArray(tenant_obj.users, user)){
1976
+ r3logger.wlog('could not find user(' + user + ') in tenant(' + tenant_name + '), remove this subkey...');
1977
+ need_update = true; // for cut this invalid subkey
1978
+ continue;
1979
+ }
1980
+
1981
+ apiutil.tryAddStringToArray(update_list, subkeylist[cnt]); // set subkey list(if update it)
1982
+
1983
+ // make result
1984
+ if(is_expand){
1985
+ tenants.push(tenant_obj);
1986
+ }else{
1987
+ tenants.push(tenant_name);
1988
+ }
1989
+ }
1990
+
1991
+ // update
1992
+ if(need_update){
1993
+ if(!dkcobj.setSubkeys(keys.USER_TENANT_TOP_KEY, update_list)){ // Update subkey "yrn:yahoo::::user:<user>:tenant"
1994
+ r3logger.elog('could not update (' + keys.USER_TENANT_TOP_KEY + ') subkey, but continue...');
1995
+ }
1996
+ }
1997
+ dkcobj.clean();
1998
+
1999
+ resobj.tenants = tenants;
2000
+
2001
+ return resobj;
2002
+ }
2003
+
2004
+ //---------------------------------------------------------
2005
+ // Remove tenant from user
2006
+ //---------------------------------------------------------
2007
+ // user user name
2008
+ // tenant tenant name
2009
+ //
2010
+ // [NOTE]
2011
+ // Call this function together with rawRemoveUserFromTenant.
2012
+ // And it should be called before rawRemoveUserFromTenant.
2013
+ //
2014
+ function rawRemoveTenantFromUser(dkcobj_permanent, user, tenant)
2015
+ {
2016
+ if(!(dkcobj_permanent instanceof Object) || !dkcobj_permanent.isPermanent()){
2017
+ r3logger.elog('parameter dkcobj_permanent is not object or not permanent');
2018
+ return false;
2019
+ }
2020
+ if(!apiutil.isSafeStrings(user, tenant)){
2021
+ r3logger.elog('parameters are wrong : user=' + JSON.stringify(user) + ', tenant=' + JSON.stringify(tenant));
2022
+ return false;
2023
+ }
2024
+
2025
+ //
2026
+ // Keys
2027
+ //
2028
+ var result = true;
2029
+ var keys = r3keys(user, tenant);
2030
+
2031
+ //
2032
+ // Get tenant list under user key
2033
+ //
2034
+ var user_tenants = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.USER_TENANT_TOP_KEY, true)); // get user's tenant list
2035
+ if(apiutil.findStringInArray(user_tenants, keys.USER_TENANT_KEY)){
2036
+ //
2037
+ // Found tenant yrn path in list, update tenant list in user
2038
+ //
2039
+ if(!apiutil.removeStringFromArray(user_tenants, keys.USER_TENANT_KEY)){
2040
+ r3logger.wlog('not found tenant(' + tenant + ') in subkey list for user(' + user + '), but continue...');
2041
+ }else{
2042
+ if(!dkcobj_permanent.setSubkeys(keys.USER_TENANT_TOP_KEY, user_tenants)){ // update subkey in "yrn:yahoo::::user:<user>:tenant"
2043
+ r3logger.elog('could not remove tenant(' + tenant + ') in subkey list for user(' + user + '), but continue...');
2044
+ result = false;
2045
+ }
2046
+ }
2047
+ }
2048
+
2049
+ //
2050
+ // Remove token for tenant key/tenant key in user
2051
+ //
2052
+ if(!dkcobj_permanent.remove(keys.USER_TENANT_SCOPE_TOKEN_KEY, false)){ // remove "yrn:yahoo::::user:<user>:tenant/<tenant>/token"
2053
+ r3logger.dlog('could not remove token key(' + keys.USER_TENANT_SCOPE_TOKEN_KEY + '), probably it is not existed.');
2054
+ }
2055
+ if(!dkcobj_permanent.remove(keys.USER_TENANT_KEY, false)){ // remove "yrn:yahoo::::user:<user>:tenant/<tenant>"
2056
+ r3logger.dlog('could not remove token key(' + keys.USER_TENANT_SCOPE_TOKEN_KEY + '), probably it is not existed.');
2057
+ }
2058
+
2059
+ return result;
2060
+ }
2061
+
2062
+ //---------------------------------------------------------
2063
+ // Remove user from tenant
2064
+ //---------------------------------------------------------
2065
+ // tenant tenant name
2066
+ // user user name
2067
+ //
2068
+ // [NOTE]
2069
+ // Call this function together with rawRemoveTenantFromUser.
2070
+ // And you have to call rawRemoveTenantFromUser before calling it.
2071
+ //
2072
+ // If there are no users or services in the target tenant, the tenant will also be deleted.
2073
+ //
2074
+ function rawRemoveUserFromTenant(dkcobj_permanent, tenant, user)
2075
+ {
2076
+ if(!(dkcobj_permanent instanceof Object) || !dkcobj_permanent.isPermanent()){
2077
+ r3logger.elog('parameter dkcobj_permanent is not object or not permanent');
2078
+ return false;
2079
+ }
2080
+ if(!apiutil.isSafeStrings(tenant, user)){
2081
+ r3logger.elog('parameters are wrong : tenant=' + JSON.stringify(tenant) + ', user=' + JSON.stringify(user));
2082
+ return false;
2083
+ }
2084
+
2085
+ //
2086
+ // Keys
2087
+ //
2088
+ var result = true;
2089
+ var keys = r3keys(user, tenant);
2090
+ var cnt;
2091
+ var tmpsubkey;
2092
+
2093
+ //
2094
+ // Get user list under tenant key
2095
+ //
2096
+ var tenant_users = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.TENANT_USER_KEY, true)); // get tenant's user list
2097
+ if(apiutil.findStringInArray(tenant_users, keys.USER_KEY)){
2098
+ //
2099
+ // Found user yrn path in list, update user list in tenant
2100
+ //
2101
+ if(!apiutil.removeStringFromArray(tenant_users, keys.USER_KEY)){
2102
+ r3logger.wlog('not found user(' + user + ') in subkey list for tenant(' + tenant + '), but continue...');
2103
+ }else{
2104
+ if(!dkcobj_permanent.setSubkeys(keys.TENANT_USER_KEY, tenant_users)){ // update subkey in "yrn:yahoo:::<tenant>:user"
2105
+ r3logger.elog('could not remove user(' + user + ') in subkey list for tenant(' + tenant + '), but continue...');
2106
+ result = false;
2107
+ }
2108
+ }
2109
+
2110
+ }
2111
+
2112
+ //
2113
+ // Check users and services for tenant, if both are empty, remove tenant
2114
+ //
2115
+ var tenant_services = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.TENANT_SERVICE_KEY, true)); // get tenant's service list
2116
+ if(apiutil.isEmptyArray(tenant_users) && apiutil.isEmptyArray(tenant_services)){
2117
+ //
2118
+ // Remove tenant subkey in "yrn:yahoo:::"
2119
+ //
2120
+ var subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.NO_SERVICE_REGION_KEY, true));
2121
+ if(!apiutil.removeStringFromArray(subkeylist, keys.MASTER_TENANT_TOP_KEY)){
2122
+ r3logger.wlog('not found tenant(' + tenant + ') in subkey list for no region key(' + keys.NO_SERVICE_REGION_KEY + '), but continue...');
2123
+ }else{
2124
+ if(!dkcobj_permanent.setSubkeys(keys.NO_SERVICE_REGION_KEY, subkeylist)){ // update subkey in "yrn:yahoo:::"
2125
+ r3logger.elog('could not remove tenant(' + tenant + ') in subkey list for no region key(' + keys.NO_SERVICE_REGION_KEY + '), but continue...');
2126
+ result = false;
2127
+ }
2128
+ }
2129
+
2130
+ //
2131
+ // Remove all resources("yrn:yahoo:<service>::<tenant>:resource:*")
2132
+ //
2133
+ subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.RESOURCE_TOP_KEY, true));
2134
+ if(!apiutil.isEmptyArray(subkeylist)){
2135
+ for(cnt = 0; cnt < subkeylist.length; ++cnt){
2136
+ tmpsubkey = apiutil.getSafeString(subkeylist[cnt]);
2137
+ if(0 !== tmpsubkey.indexOf(keys.RESOURCE_TOP_KEY + ':')){
2138
+ r3logger.wlog('tenant(' + tenant + ') has unknown formatted resource value(' + tmpsubkey + ')');
2139
+ continue;
2140
+ }
2141
+ // cut yrn path
2142
+ tmpsubkey = tmpsubkey.replace(keys.RESOURCE_TOP_KEY + ':', '');
2143
+
2144
+ if(!rawRemovePolicyEx(dkcobj_permanent, tenant, null, tmpsubkey)){
2145
+ r3logger.elog('failed to remove resource(' + tmpsubkey + ') in tenant(' + tenant + '), but continue...');
2146
+ result = false;
2147
+ }
2148
+ }
2149
+ }
2150
+
2151
+ //
2152
+ // Remove all policies("yrn:yahoo:<service>::<tenant>:policy:*")
2153
+ //
2154
+ subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.POLICY_TOP_KEY, true));
2155
+ if(!apiutil.isEmptyArray(subkeylist)){
2156
+ for(cnt = 0; cnt < subkeylist.length; ++cnt){
2157
+ tmpsubkey = apiutil.getSafeString(subkeylist[cnt]);
2158
+ if(0 !== tmpsubkey.indexOf(keys.POLICY_TOP_KEY + ':')){
2159
+ r3logger.wlog('tenant(' + tenant + ') has unknown formatted policy value(' + tmpsubkey + ')');
2160
+ continue;
2161
+ }
2162
+ // cut yrn path
2163
+ tmpsubkey = tmpsubkey.replace(keys.POLICY_TOP_KEY + ':', '');
2164
+
2165
+ if(!rawRemovePolicyEx(dkcobj_permanent, tenant, null, tmpsubkey)){
2166
+ r3logger.elog('failed to remove policy(' + tmpsubkey + ') in tenant(' + tenant + '), but continue...');
2167
+ result = false;
2168
+ }
2169
+ }
2170
+ }
2171
+
2172
+ //
2173
+ // Remove all roles("yrn:yahoo:<service>::<tenant>:role:*")
2174
+ //
2175
+ subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.ROLE_TOP_KEY, true));
2176
+ if(!apiutil.isEmptyArray(subkeylist)){
2177
+ for(cnt = 0; cnt < subkeylist.length; ++cnt){
2178
+ tmpsubkey = apiutil.getSafeString(subkeylist[cnt]);
2179
+ if(0 !== tmpsubkey.indexOf(keys.ROLE_TOP_KEY + ':')){
2180
+ r3logger.wlog('tenant(' + tenant + ') has unknown formatted role value(' + tmpsubkey + ')');
2181
+ continue;
2182
+ }
2183
+ // cut yrn path
2184
+ tmpsubkey = tmpsubkey.replace(keys.ROLE_TOP_KEY + ':', '');
2185
+
2186
+ if(!rawRemoveRoleEx(dkcobj_permanent, tenant, null, tmpsubkey)){
2187
+ r3logger.elog('failed to remove role(' + tmpsubkey + ') in tenant(' + tenant + '), but continue...');
2188
+ result = false;
2189
+ }
2190
+ }
2191
+ }
2192
+
2193
+ //
2194
+ // Remove all subkey in tenant
2195
+ //
2196
+ if(!dkcobj_permanent.remove(keys.TENANT_ID_KEY, false)){ // remove "yrn:yahoo:::<tenant>:id"
2197
+ r3logger.elog('could not remove id key(' + keys.TENANT_ID_KEY + '), probably it is not existed.');
2198
+ result = false;
2199
+ }
2200
+ if(!dkcobj_permanent.remove(keys.TENANT_DESC_KEY, false)){ // remove "yrn:yahoo:::<tenant>:desc"
2201
+ r3logger.elog('could not remove description key(' + keys.TENANT_DESC_KEY + '), probably it is not existed.');
2202
+ result = false;
2203
+ }
2204
+ if(!dkcobj_permanent.remove(keys.TENANT_DISP_KEY, false)){ // remove "yrn:yahoo:::<tenant>:display"
2205
+ r3logger.elog('could not remove display key(' + keys.TENANT_DISP_KEY + '), probably it is not existed.');
2206
+ result = false;
2207
+ }
2208
+ if(!dkcobj_permanent.remove(keys.TENANT_USER_KEY, false)){ // remove "yrn:yahoo:::<tenant>:user"
2209
+ r3logger.elog('could not remove user key(' + keys.TENANT_USER_KEY + '), probably it is not existed.');
2210
+ result = false;
2211
+ }
2212
+ if(!dkcobj_permanent.remove(keys.TENANT_SERVICE_KEY, false)){ // remove "yrn:yahoo:::<tenant>:service"
2213
+ r3logger.elog('could not remove service key(' + keys.TENANT_SERVICE_KEY + '), probably it is not existed.');
2214
+ result = false;
2215
+ }
2216
+
2217
+ //
2218
+ // Remove tenant key
2219
+ //
2220
+ if(!dkcobj_permanent.remove(keys.MASTER_TENANT_TOP_KEY, false)){ // remove "yrn:yahoo:::<tenant>"
2221
+ r3logger.elog('could not remove service key(' + keys.MASTER_TENANT_TOP_KEY + '), probably it is not existed.');
2222
+ result = false;
2223
+ }
2224
+ }
2225
+ return result;
2226
+ }
2227
+
2228
+ //---------------------------------------------------------
2229
+ // Common remove user from local tenant
2230
+ //---------------------------------------------------------
2231
+ // tenant : tenant name
2232
+ // user : user name
2233
+ // id : tenant id
2234
+ //
2235
+ // result {
2236
+ // result: true/false
2237
+ // message: null or error message
2238
+ // }
2239
+ //
2240
+ function rawRemoveUserFromLocalTenant(tenant, user, id)
2241
+ {
2242
+ var resobj = {result: true, message: null};
2243
+
2244
+ if(!apiutil.isSafeStrings(tenant, user, id)){
2245
+ resobj.result = false;
2246
+ resobj.message = 'some parameters are wrong : tenant=' + JSON.stringify(tenant) + ', user=' + JSON.stringify(user) + ', id=' + JSON.stringify(id);
2247
+ r3logger.elog(resobj.message);
2248
+ return resobj;
2249
+ }
2250
+
2251
+ var dkcobj = k2hdkc(dkcconf, dkcport, dkccuk, true, false); // use permanent object(need to clean)
2252
+ if(!rawInitKeyHierarchy(dkcobj)){
2253
+ resobj.result = false;
2254
+ resobj.message = 'Not initialize yet, or configuration is not set';
2255
+ r3logger.elog(resobj.message);
2256
+ dkcobj.clean();
2257
+ return resobj;
2258
+ }
2259
+
2260
+ //
2261
+ // Keys
2262
+ //
2263
+ var keys = r3keys(user, tenant);
2264
+
2265
+ //
2266
+ // Check tenant name
2267
+ //
2268
+ if(0 !== tenant.indexOf(keys.VALUE_PREFIX_LOCAL_TENANT)){
2269
+ // 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;
2275
+ }
2276
+
2277
+ //
2278
+ // Find tenant
2279
+ //
2280
+ var result = rawFindTenantEx(dkcobj, tenant, user, id);
2281
+ 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;
2287
+ }
2288
+
2289
+ //
2290
+ // Check user list in tenant
2291
+ //
2292
+ 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;
2298
+ }
2299
+
2300
+ //
2301
+ // Remove tenant from user
2302
+ //
2303
+ if(!rawRemoveTenantFromUser(dkcobj, user, tenant)){
2304
+ resobj.result = false;
2305
+ resobj.message = 'failed to remove tenant(' + tenant + ') from user(' + user + ').';
2306
+ r3logger.elog(resobj.message);
2307
+ dkcobj.clean();
2308
+ return resobj;
2309
+ }
2310
+
2311
+ //
2312
+ // Remove user from tenant
2313
+ //
2314
+ if(!rawRemoveUserFromTenant(dkcobj, tenant, user)){
2315
+ resobj.result = false;
2316
+ resobj.message = 'failed to remove user(' + user + ') from tenant(' + tenant + ').';
2317
+ r3logger.elog(resobj.message);
2318
+ dkcobj.clean();
2319
+ return resobj;
2320
+ }
2321
+ dkcobj.clean();
2322
+
2323
+ return resobj;
2324
+ }
2325
+
2326
+ //---------------------------------------------------------
2327
+ // Add tenant to existed user key
1554
2328
  //---------------------------------------------------------
1555
2329
  // user : user name
1556
2330
  // tenant : tenant name
2331
+ //
2332
+ // result : null for failure
2333
+ // user yrn full path for success
2334
+ //
2335
+ // [NOTE]
2336
+ // Both user and service can not be specified at same time.
2337
+ // This function create keys without resource/policy/role, you must be careful for service
2338
+ // case.
2339
+ //
2340
+ function rawAddTenantToExistedUser(dkcobj_permanent, user, tenant)
2341
+ {
2342
+ if(!(dkcobj_permanent instanceof Object) || !dkcobj_permanent.isPermanent()){
2343
+ r3logger.elog('parameter dkcobj_permanent is not object or not permanent');
2344
+ return null;
2345
+ }
2346
+ if(!apiutil.isSafeStrings(user, tenant)){
2347
+ r3logger.elog('some parameters are wrong : user=' + JSON.stringify(user) + ', tenant=' + JSON.stringify(tenant));
2348
+ return null;
2349
+ }
2350
+
2351
+ var keys = r3keys(user, tenant);
2352
+
2353
+ //
2354
+ // Check user exists
2355
+ //
2356
+ var subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.USER_KEY, true));
2357
+ if(apiutil.isEmptyArray(subkeylist) || !apiutil.findStringInArray(subkeylist, keys.USER_ID_KEY)){
2358
+ r3logger.elog('user(' + user + ') does not exist.');
2359
+ return null;
2360
+ }
2361
+
2362
+ //
2363
+ // Add tenant key to user subkey list
2364
+ //
2365
+ subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.USER_TENANT_TOP_KEY, true));
2366
+ if(apiutil.tryAddStringToArray(subkeylist, keys.USER_TENANT_KEY)){
2367
+ if(!dkcobj_permanent.setSubkeys(keys.USER_TENANT_TOP_KEY, subkeylist)){ // add subkey [..., yrn:yahoo::::user:<user>:tenant/<tenant>] -> yrn:yahoo::::user:<user>:tenant
2368
+ r3logger.elog('could not add ' + keys.USER_TENANT_KEY + ' subkey under ' + keys.USER_TENANT_TOP_KEY + ' key');
2369
+ return null;
2370
+ }
2371
+ }
2372
+
2373
+ // [NOTE]
2374
+ // We do not create "yrn:yahoo::::user:<user>:tenant/<tenant>" keys
2375
+ // These keys have token(scoped and unscoped) value, these values is set another function.
2376
+ //
2377
+
2378
+ return keys.USER_KEY;
2379
+ }
2380
+
2381
+ //---------------------------------------------------------
2382
+ // Common raw create tenant key
2383
+ //---------------------------------------------------------
2384
+ // user : user name(existed main user)
2385
+ // tenant : tenant name
1557
2386
  // service : service name
1558
2387
  // id : tenant id, if user is specified(service is specified, do not need this)
1559
2388
  // desc : tenant description, if user is specified(service is specified, do not need this)
1560
2389
  // 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)
1561
2391
  //
1562
2392
  // [NOTE]
1563
2393
  // Both user and service can not be specified at same time.
1564
2394
  // This function create keys without resource/policy/role, you must be careful for service
1565
2395
  // case.
1566
2396
  //
1567
- function rawCreateTenantEx(dkcobj_permanent, user, tenant, service, id, desc, display)
2397
+ function rawCreateTenantEx(dkcobj_permanent, user, tenant, service, id, desc, display, other_users)
1568
2398
  {
1569
2399
  if(!(dkcobj_permanent instanceof Object) || !dkcobj_permanent.isPermanent()){
1570
2400
  r3logger.elog('parameter dkcobj_permanent is not object or not permanent');
@@ -1589,12 +2419,19 @@ function rawCreateTenantEx(dkcobj_permanent, user, tenant, service, id, desc, di
1589
2419
  id = String(id);
1590
2420
  }
1591
2421
  service = null;
2422
+
2423
+ if(apiutil.isEmptyArray(other_users)){
2424
+ other_users = [];
2425
+ }
2426
+ apiutil.tryAddStringToArray(other_users, user); // add user to other_users
2427
+
1592
2428
  }else if(apiutil.isSafeString(service) && !apiutil.isSafeString(user)){
1593
2429
  //
1594
2430
  // case: specified service parameter
1595
2431
  //
1596
- service = service.toLowerCase();
1597
- user = null;
2432
+ service = service.toLowerCase();
2433
+ user = null;
2434
+ other_users = null;
1598
2435
  }else{
1599
2436
  r3logger.elog('some parameters are wrong(both are empty or not empty) : service=' + JSON.stringify(service) + ', user=' + JSON.stringify(user));
1600
2437
  return false;
@@ -1792,9 +2629,14 @@ function rawCreateTenantEx(dkcobj_permanent, user, tenant, service, id, desc, di
1792
2629
  return false;
1793
2630
  }
1794
2631
  }
1795
- subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.TENANT_USER_KEY, true));
1796
- if(apiutil.tryAddStringToArray(subkeylist, keys.USER_KEY)){
1797
- if(!dkcobj_permanent.setSubkeys(keys.TENANT_USER_KEY, subkeylist)){ // add subkey yrn:yahoo::::user:<user> -> yrn:yahoo:::<tenant>:user
2632
+ // [NOTE]
2633
+ // Only add direct users here.
2634
+ //
2635
+ var user_subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.TENANT_USER_KEY, true));
2636
+ user_subkeylist.sort();
2637
+ if(apiutil.tryAddStringToArray(user_subkeylist, keys.USER_KEY)){
2638
+ user_subkeylist.sort();
2639
+ if(!dkcobj_permanent.setSubkeys(keys.TENANT_USER_KEY, user_subkeylist)){ // add subkey yrn:yahoo::::user:<user> -> yrn:yahoo:::<tenant>:user
1798
2640
  r3logger.elog('could not add ' + keys.USER_KEY + ' subkey under ' + keys.TENANT_USER_KEY + ' key');
1799
2641
  return false;
1800
2642
  }
@@ -1817,6 +2659,34 @@ function rawCreateTenantEx(dkcobj_permanent, user, tenant, service, id, desc, di
1817
2659
  return false;
1818
2660
  }
1819
2661
  }
2662
+
2663
+ //
2664
+ // Add other users(with user) to tenant
2665
+ //
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
+ }
2679
+ }
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
+ }
2688
+ }
2689
+ }
1820
2690
  }
1821
2691
 
1822
2692
  //
@@ -1981,17 +2851,18 @@ function rawCheckTenantEnable(dkcobj_permanent, tenant, servicename)
1981
2851
  //---------------------------------------------------------
1982
2852
  // create tenant key(no service)
1983
2853
  //---------------------------------------------------------
2854
+ // user : user name
1984
2855
  // tenant : tenant name
1985
2856
  // id : tenant id
1986
2857
  // desc : tenant description
1987
2858
  // display : display name
1988
- // user : user name
2859
+ // other_users : other users in this tenant (this parameter is invalid if service is specified)
1989
2860
  //
1990
2861
  // [NOTE]
1991
2862
  // This function does not check the user is a member in tenant, then
1992
2863
  // you must check it before calling this function.
1993
2864
  //
1994
- function rawCreateTenant(user, tenant, id, desc, display)
2865
+ function rawCreateTenant(user, tenant, id, desc, display, other_users)
1995
2866
  {
1996
2867
  var resobj = {result: true, message: null};
1997
2868
 
@@ -2026,7 +2897,7 @@ function rawCreateTenant(user, tenant, id, desc, display)
2026
2897
  //
2027
2898
  // Create tenant top
2028
2899
  //
2029
- if(!rawCreateTenantEx(dkcobj, user, tenant, null, id, desc, display)){
2900
+ if(!rawCreateTenantEx(dkcobj, user, tenant, null, id, desc, display, other_users)){
2030
2901
  resobj.result = false;
2031
2902
  resobj.message = 'could not create tenant(' + tenant + ') with id(' + id + '), desc(' + JSON.stringify(desc) + '), display(' + JSON.stringify(display) + '), user(' + user + ')';
2032
2903
  r3logger.elog(resobj.message);
@@ -2822,10 +3693,14 @@ function rawRemoveComprehensionByNewTenants(user, tenant_list)
2822
3693
  var tg_tenant_keys = new Array(0); // tenant key name which has user name who must be removed
2823
3694
  var pattern = new RegExp('^' + notenant_keys.USER_TENANT_COMMON_KEY + '(.*)'); // regex = /^yrn:yahoo::::user:<user>\:tenant\/(.*)/
2824
3695
  var is_changed = false;
3696
+ var localtenant_prefix = notenant_keys.USER_TENANT_COMMON_KEY + notenant_keys.VALUE_PREFIX_LOCAL_TENANT; // "yrn:yahoo::::user:<user>:tenant/<local tenant prefix>"
3697
+
2825
3698
  if(!apiutil.isEmptyArray(cur_user_tenants)){
2826
3699
  for(cnt = 0; cnt < cur_user_tenants.length; ){
2827
3700
  var cur_tenant = cur_user_tenants[cnt].toLowerCase();
2828
- if(!apiutil.findStringInArray(new_user_tenants, cur_tenant)){
3701
+
3702
+ // check tenant in list and not local tenant
3703
+ if(!apiutil.findStringInArray(new_user_tenants, cur_tenant) && 0 !== cur_tenant.indexOf(localtenant_prefix)){
2829
3704
  // not found current tenant key in new tenants list, so add removed key list
2830
3705
  cur_user_tenants.splice(cnt, 1);
2831
3706
  rm_user_tenants.push(cur_tenant);
@@ -10908,12 +11783,12 @@ function rawCompareChildrenListName(child1, child2)
10908
11783
  //
10909
11784
  // These functions initializing tenant is without service.
10910
11785
  //
10911
- exports.initTenant = function(tenantname, id, desc, display, user)
11786
+ exports.initTenant = function(tenantname, id, desc, display, user, other_users)
10912
11787
  {
10913
11788
  //
10914
11789
  // Must initialize service key before calling this if specified service parameter
10915
11790
  //
10916
- return rawCreateTenant(user, tenantname, id, desc, display);
11791
+ return rawCreateTenant(user, tenantname, id, desc, display, other_users);
10917
11792
  };
10918
11793
 
10919
11794
  exports.initUser = function(user, id, username, tenant)
@@ -10933,6 +11808,21 @@ exports.initUserTenant = function(user, userid, username, tenant, tenantid, tena
10933
11808
  return resobj;
10934
11809
  };
10935
11810
 
11811
+ exports.findTenant = function(tenant, user, id)
11812
+ {
11813
+ return rawFindTenant(tenant, user, id);
11814
+ };
11815
+
11816
+ exports.listLocalTenant = function(user, is_expand)
11817
+ {
11818
+ return rawListLocalTenant(user, is_expand);
11819
+ };
11820
+
11821
+ exports.removeUserFromLocalTenant = function(tenant, user, id)
11822
+ {
11823
+ return rawRemoveUserFromLocalTenant(tenant, user, id);
11824
+ };
11825
+
10936
11826
  exports.getUserId = function(username)
10937
11827
  {
10938
11828
  return rawGetUserId(username);