Skip to content

Commit 24807bb

Browse files
cwperkscliu123DarshitChanpura
authored
[Saved Object Aggregation View] Use namespace registry to add tenant filter (#1169)
Signed-off-by: Craig Perkins <[email protected]> Signed-off-by: Chang Liu <[email protected]> Co-authored-by: Chang Liu <[email protected]> Co-authored-by: Darshit Chanpura <[email protected]>
1 parent f815e3c commit 24807bb

File tree

4 files changed

+117
-14
lines changed

4 files changed

+117
-14
lines changed

public/apps/configuration/utils/tenant-utils.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {
3838
import { httpDelete, httpGet, httpPost } from './request-utils';
3939
import { getResourceUrl } from './resource-utils';
4040
import {
41+
DEFAULT_TENANT,
4142
GLOBAL_TENANT_RENDERING_TEXT,
4243
GLOBAL_TENANT_SYMBOL,
4344
globalTenantName,
@@ -181,6 +182,33 @@ export function transformRoleTenantPermissions(
181182
}));
182183
}
183184

185+
export function getNamespacesToRegister(accountInfo: any) {
186+
const tenants = accountInfo.tenants || {};
187+
const availableTenantNames = Object.keys(tenants!);
188+
const namespacesToRegister = availableTenantNames.map((tenant) => {
189+
if (tenant === globalTenantName) {
190+
return {
191+
id: GLOBAL_USER_DICT.Value,
192+
name: GLOBAL_USER_DICT.Label,
193+
};
194+
} else if (tenant === accountInfo.user_name) {
195+
return {
196+
id: `${PRIVATE_USER_DICT.Value}${accountInfo.user_name}`,
197+
name: PRIVATE_USER_DICT.Label,
198+
};
199+
}
200+
return {
201+
id: tenant,
202+
name: tenant,
203+
};
204+
});
205+
namespacesToRegister.push({
206+
id: DEFAULT_TENANT,
207+
name: DEFAULT_TENANT,
208+
});
209+
return namespacesToRegister;
210+
}
211+
184212
export const tenantColumn = {
185213
id: 'tenant_column',
186214
euiColumn: {

public/apps/configuration/utils/test/tenant-utils.test.tsx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
transformRoleTenantPermissionData,
2525
getTenantPermissionType,
2626
transformRoleTenantPermissions,
27+
getNamespacesToRegister,
2728
} from '../tenant-utils';
2829
import {
2930
RoleViewTenantInvalidText,
@@ -282,4 +283,63 @@ describe('Tenant list utils', () => {
282283
expect(result[0]).toMatchObject(expectedRoleTenantPermissionView);
283284
});
284285
});
286+
287+
describe('get list of namespaces to register', () => {
288+
it('resolves to list of namespaces with a custom tenant', () => {
289+
const authInfo = {
290+
user_name: 'user1',
291+
tenants: {
292+
global_tenant: true,
293+
user1_tenant: true,
294+
user1: true,
295+
},
296+
};
297+
const expectedNamespaces = [
298+
{
299+
id: GLOBAL_USER_DICT.Value,
300+
name: GLOBAL_USER_DICT.Label,
301+
},
302+
{
303+
id: 'user1_tenant',
304+
name: 'user1_tenant',
305+
},
306+
{
307+
id: `${PRIVATE_USER_DICT.Value}user1`,
308+
name: PRIVATE_USER_DICT.Label,
309+
},
310+
{
311+
id: 'default',
312+
name: 'default',
313+
},
314+
];
315+
const result = getNamespacesToRegister(authInfo);
316+
expect(result).toMatchObject(expectedNamespaces);
317+
});
318+
319+
it('resolves to list of namespaces without a custom tenant', () => {
320+
const authInfo = {
321+
user_name: 'user1',
322+
tenants: {
323+
global_tenant: true,
324+
user1: true,
325+
},
326+
};
327+
const expectedNamespaces = [
328+
{
329+
id: GLOBAL_USER_DICT.Value,
330+
name: GLOBAL_USER_DICT.Label,
331+
},
332+
{
333+
id: `${PRIVATE_USER_DICT.Value}user1`,
334+
name: PRIVATE_USER_DICT.Label,
335+
},
336+
{
337+
id: 'default',
338+
name: 'default',
339+
},
340+
];
341+
const result = getNamespacesToRegister(authInfo);
342+
expect(result).toMatchObject(expectedNamespaces);
343+
});
344+
});
285345
});

public/plugin.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import {
4646
} from './types';
4747
import { addTenantToShareURL } from './services/shared-link';
4848
import { interceptError } from './utils/logout-utils';
49-
import { tenantColumn } from './apps/configuration/utils/tenant-utils';
49+
import { tenantColumn, getNamespacesToRegister } from './apps/configuration/utils/tenant-utils';
5050

5151
async function hasApiPermission(core: CoreSetup): Promise<boolean | undefined> {
5252
try {
@@ -157,6 +157,13 @@ export class SecurityPlugin
157157
deps.savedObjectsManagement.columns.register(
158158
(tenantColumn as unknown) as SavedObjectsManagementColumn<string>
159159
);
160+
if (!!accountInfo) {
161+
const namespacesToRegister = getNamespacesToRegister(accountInfo);
162+
deps.savedObjectsManagement.namespaces.registerAlias('Tenant');
163+
namespacesToRegister.forEach((ns) => {
164+
deps.savedObjectsManagement.namespaces.register(ns as SavedObjectsManagementNamespace);
165+
});
166+
}
160167
}
161168

162169
// Return methods that should be available to other plugins

server/saved_objects/saved_objects_wrapper.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -104,24 +104,32 @@ export class SecuritySavedObjectsClientWrapper {
104104
availableTenantNames.splice(index, 1);
105105
}
106106
}
107-
const typeToNamespacesMap: any = {};
108107
if (isPrivateTenant(selectedTenant!)) {
109108
namespaceValue = selectedTenant! + username;
110109
}
111-
const searchTypes = Array.isArray(options.type) ? options.type : [options.type];
112-
searchTypes.forEach((t) => {
113-
if ('namespaces' in options) {
114-
typeToNamespacesMap[t] = options.namespaces;
115-
} else {
116-
typeToNamespacesMap[t] = availableTenantNames;
110+
if (!!options.namespaces) {
111+
const namespacesToInclude = Array.isArray(options.namespaces)
112+
? options.namespaces
113+
: [options.namespaces];
114+
const typeToNamespacesMap: any = {};
115+
const searchTypes = Array.isArray(options.type) ? options.type : [options.type];
116+
searchTypes.forEach((t) => {
117+
typeToNamespacesMap[t] = namespacesToInclude;
118+
});
119+
if (searchTypes.includes('config')) {
120+
if (namespacesToInclude.includes(namespaceValue)) {
121+
typeToNamespacesMap.config = [namespaceValue];
122+
} else {
123+
delete typeToNamespacesMap.config;
124+
}
117125
}
118-
});
119-
if ('config' in typeToNamespacesMap) {
120-
typeToNamespacesMap.config = [namespaceValue];
126+
127+
options.typeToNamespacesMap = new Map(Object.entries(typeToNamespacesMap));
128+
options.type = '';
129+
options.namespaces = [];
130+
} else {
131+
options.namespaces = [namespaceValue];
121132
}
122-
options.typeToNamespacesMap = new Map(Object.entries(typeToNamespacesMap));
123-
options.type = '';
124-
options.namespaces = [];
125133

126134
return await wrapperOptions.client.find(options);
127135
};

0 commit comments

Comments
 (0)