adapt Core userSettings service to no longer depends on the security plugin (#181538)

## Summary

Part of https://github.com/elastic/kibana/issues/174578

Adapt Core's `userSettings` service to leverage Core's `userProfile`
service instead of the `security` plugin

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Pierre Gayvallet 2024-04-29 09:34:59 +02:00 committed by GitHub
parent 2f5897a70c
commit 8bf0c419cc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 201 additions and 496 deletions

View file

@ -272,9 +272,7 @@ export function createPluginSetupContext<TPlugin, TPluginDependencies>({
registerGlobal: deps.uiSettings.registerGlobal,
setAllowlist: deps.uiSettings.setAllowlist,
},
userSettings: {
setUserProfileSettings: deps.userSettings.setUserProfileSettings,
},
userSettings: {},
getStartServices: () => plugin.startDependencies,
deprecations: deps.deprecations.getRegistry(plugin.name),
coreUsageData: {

View file

@ -129,7 +129,7 @@ describe('bootstrapRenderer', () => {
});
it('calls getThemeTag with values (true/dark) from the UserSettingsService when provided', async () => {
userSettingsService.getUserSettingDarkMode.mockReturnValueOnce(true);
userSettingsService.getUserSettingDarkMode.mockResolvedValueOnce(true);
renderer = bootstrapRendererFactory({
auth,
@ -155,7 +155,7 @@ describe('bootstrapRenderer', () => {
});
it('calls getThemeTag with values (false/light) from the UserSettingsService when provided', async () => {
userSettingsService.getUserSettingDarkMode.mockReturnValueOnce(false);
userSettingsService.getUserSettingDarkMode.mockResolvedValueOnce(false);
renderer = bootstrapRendererFactory({
auth,
@ -181,7 +181,7 @@ describe('bootstrapRenderer', () => {
});
it('calls getThemeTag with values from the UiSettingsClient when values (false/light) from UserSettingsService are `undefined`', async () => {
userSettingsService.getUserSettingDarkMode.mockReturnValueOnce(undefined);
userSettingsService.getUserSettingDarkMode.mockResolvedValueOnce(undefined);
renderer = bootstrapRendererFactory({
auth,
@ -207,7 +207,7 @@ describe('bootstrapRenderer', () => {
});
it('calls getThemeTag with values from the UiSettingsClient when values (true/dark) from UserSettingsService are `undefined`', async () => {
userSettingsService.getUserSettingDarkMode.mockReturnValueOnce(undefined);
userSettingsService.getUserSettingDarkMode.mockResolvedValueOnce(undefined);
renderer = bootstrapRendererFactory({
auth,

View file

@ -219,6 +219,7 @@ test('runs services on "start"', async () => {
expect(mockCustomBrandingService.start).toHaveBeenCalledTimes(1);
expect(mockSecurityService.start).toHaveBeenCalledTimes(1);
expect(mockUserProfileService.start).toHaveBeenCalledTimes(1);
expect(mockUserSettingsService.start).toHaveBeenCalledTimes(1);
});
test('does not fail on "setup" if there are unused paths detected', async () => {

View file

@ -386,6 +386,7 @@ export class Server {
const analyticsStart = this.analytics.start();
const securityStart = this.security.start();
const userProfileStart = this.userProfile.start();
this.userSettingsService.start({ userProfile: userProfileStart });
const executionContextStart = this.executionContext.start();
const docLinkStart = this.docLinks.start();

View file

@ -6,5 +6,5 @@
* Side Public License, v 1.
*/
export { UserSettingsService } from './user_settings_service';
export type { InternalUserSettingsServiceSetup } from './user_settings_service';
export { UserSettingsService } from './src/user_settings_service';
export type { InternalUserSettingsServiceSetup } from './src/user_settings_service';

View file

@ -0,0 +1,98 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { mockCoreContext } from '@kbn/core-base-server-mocks';
import { httpServerMock } from '@kbn/core-http-server-mocks';
import { userProfileServiceMock } from '@kbn/core-user-profile-server-mocks';
import type { UserProfileWithSecurity } from '@kbn/core-user-profile-common';
import { UserSettingsService } from './user_settings_service';
describe('#setup', () => {
let coreContext: ReturnType<typeof mockCoreContext.create>;
let service: UserSettingsService;
let startDeps: { userProfile: ReturnType<typeof userProfileServiceMock.createInternalStart> };
beforeEach(() => {
coreContext = mockCoreContext.create();
service = new UserSettingsService(coreContext);
startDeps = {
userProfile: userProfileServiceMock.createInternalStart(),
};
});
const createUserProfile = (darkMode: string | undefined): UserProfileWithSecurity => {
return {
data: {
userSettings: {
darkMode,
},
},
} as unknown as UserProfileWithSecurity;
};
it('fetches userSettings when client is set and returns `true` when `darkMode` is set to `dark`', async () => {
startDeps.userProfile.getCurrent.mockResolvedValue(createUserProfile('dark'));
const { getUserSettingDarkMode } = service.setup();
service.start(startDeps);
const kibanaRequest = httpServerMock.createKibanaRequest();
const darkMode = await getUserSettingDarkMode(kibanaRequest);
expect(darkMode).toEqual(true);
expect(startDeps.userProfile.getCurrent).toHaveBeenCalledTimes(1);
expect(startDeps.userProfile.getCurrent).toHaveBeenCalledWith({
request: kibanaRequest,
dataPath: 'userSettings',
});
});
it('fetches userSettings when client is set and returns `false` when `darkMode` is set to `light`', async () => {
startDeps.userProfile.getCurrent.mockResolvedValue(createUserProfile('light'));
const { getUserSettingDarkMode } = service.setup();
service.start(startDeps);
const kibanaRequest = httpServerMock.createKibanaRequest();
const darkMode = await getUserSettingDarkMode(kibanaRequest);
expect(darkMode).toEqual(false);
expect(startDeps.userProfile.getCurrent).toHaveBeenCalledTimes(1);
expect(startDeps.userProfile.getCurrent).toHaveBeenCalledWith({
request: kibanaRequest,
dataPath: 'userSettings',
});
});
it('fetches userSettings when client is set and returns `undefined` when `darkMode` is set to `` (the default value)', async () => {
startDeps.userProfile.getCurrent.mockResolvedValue(createUserProfile(''));
const { getUserSettingDarkMode } = service.setup();
service.start(startDeps);
const kibanaRequest = httpServerMock.createKibanaRequest();
const darkMode = await getUserSettingDarkMode(kibanaRequest);
expect(darkMode).toEqual(undefined);
expect(startDeps.userProfile.getCurrent).toHaveBeenCalledTimes(1);
expect(startDeps.userProfile.getCurrent).toHaveBeenCalledWith({
request: kibanaRequest,
dataPath: 'userSettings',
});
});
it('does not fetch userSettings when client is not set, returns `undefined`, and logs a debug statement', async () => {
const { getUserSettingDarkMode } = service.setup();
const kibanaRequest = httpServerMock.createKibanaRequest();
const darkMode = await getUserSettingDarkMode(kibanaRequest);
expect(darkMode).toEqual(undefined);
expect(coreContext.logger.get().debug).toHaveBeenCalledWith('userProfile not set');
});
});

View file

@ -0,0 +1,73 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import type { CoreContext } from '@kbn/core-base-server-internal';
import type { Logger } from '@kbn/logging';
import type { KibanaRequest } from '@kbn/core-http-server';
import type { DarkModeValue } from '@kbn/core-ui-settings-common';
import type { InternalUserProfileServiceStart } from '@kbn/core-user-profile-server-internal';
export interface UserSettingsServiceStartDeps {
userProfile: InternalUserProfileServiceStart;
}
const userSettingsDataPath = 'userSettings';
/**
* @internal
*/
export interface InternalUserSettingsServiceSetup {
getUserSettingDarkMode: (request: KibanaRequest) => Promise<DarkModeValue | undefined>;
}
/**
* @internal
*/
export class UserSettingsService {
private logger: Logger;
private userProfile?: InternalUserProfileServiceStart;
constructor(coreContext: CoreContext) {
this.logger = coreContext.logger.get('user-settings-service');
}
public setup(): InternalUserSettingsServiceSetup {
return {
getUserSettingDarkMode: async (request: KibanaRequest) => {
const userSettings = await this.getSettings(request);
return getUserSettingDarkMode(userSettings);
},
};
}
public start(deps: UserSettingsServiceStartDeps) {
this.userProfile = deps.userProfile;
}
private async getSettings(request: KibanaRequest): Promise<Record<string, string>> {
if (this.userProfile) {
const userProfile = await this.userProfile.getCurrent({
request,
dataPath: userSettingsDataPath,
});
return (userProfile?.data?.[userSettingsDataPath] ?? {}) as Record<string, string>;
} else {
this.logger.debug('userProfile not set');
return {};
}
}
}
const getUserSettingDarkMode = (
userSettings: Record<string, string>
): DarkModeValue | undefined => {
if (userSettings?.darkMode) {
return userSettings.darkMode.toUpperCase() === 'DARK';
}
return undefined;
};

View file

@ -13,8 +13,10 @@
"@kbn/core-base-server-internal",
"@kbn/logging",
"@kbn/core-http-server-mocks",
"@kbn/core-user-settings-server",
"@kbn/core-ui-settings-common",
"@kbn/core-user-profile-server-mocks",
"@kbn/core-user-profile-common",
"@kbn/core-user-profile-server-internal",
],
"include": [
"**/*.ts",

View file

@ -1,82 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { mockCoreContext } from '@kbn/core-base-server-mocks';
import { UserSettingsService } from './user_settings_service';
import { httpServerMock } from '@kbn/core-http-server-mocks';
describe('#setup', () => {
const coreContext: ReturnType<typeof mockCoreContext.create> = mockCoreContext.create();
const { createKibanaRequest } = httpServerMock;
it('fetches userSettings when client is set and returns `true` when `darkMode` is set to `dark`', async () => {
const service = new UserSettingsService(coreContext);
const { setUserProfileSettings, getUserSettingDarkMode } = service.setup();
const userProfileContract = {
get: jest.fn().mockReturnValueOnce(Promise.resolve({ darkMode: 'dark' })),
};
setUserProfileSettings(userProfileContract);
const kibanaRequest = createKibanaRequest();
const darkMode = await getUserSettingDarkMode(kibanaRequest);
expect(darkMode).toEqual(true);
expect(userProfileContract.get).toHaveBeenCalledTimes(1);
expect(userProfileContract.get).toHaveBeenCalledWith(kibanaRequest);
});
it('fetches userSettings when client is set and returns `false` when `darkMode` is set to `light`', async () => {
const service = new UserSettingsService(coreContext);
const { setUserProfileSettings, getUserSettingDarkMode } = service.setup();
const userProfileContract = {
get: jest.fn().mockReturnValueOnce(Promise.resolve({ darkMode: 'light' })),
};
setUserProfileSettings(userProfileContract);
const kibanaRequest = createKibanaRequest();
const darkMode = await getUserSettingDarkMode(kibanaRequest);
expect(darkMode).toEqual(false);
expect(userProfileContract.get).toHaveBeenCalledTimes(1);
expect(userProfileContract.get).toHaveBeenCalledWith(kibanaRequest);
});
it('fetches userSettings when client is set and returns `undefined` when `darkMode` is set to `` (the default value)', async () => {
const service = new UserSettingsService(coreContext);
const { setUserProfileSettings, getUserSettingDarkMode } = service.setup();
const userProfileContract = {
get: jest.fn().mockReturnValueOnce(Promise.resolve({ darkMode: '' })),
};
setUserProfileSettings(userProfileContract);
const kibanaRequest = createKibanaRequest();
const darkMode = await getUserSettingDarkMode(kibanaRequest);
expect(darkMode).toEqual(undefined);
expect(userProfileContract.get).toHaveBeenCalledTimes(1);
expect(userProfileContract.get).toHaveBeenCalledWith(kibanaRequest);
});
it('does not fetch userSettings when client is not set, returns `undefined`, and logs a debug statement', async () => {
const service = new UserSettingsService(coreContext);
const { getUserSettingDarkMode } = service.setup();
const kibanaRequest = createKibanaRequest();
const darkMode = await getUserSettingDarkMode(kibanaRequest);
expect(darkMode).toEqual(undefined);
expect(coreContext.logger.get().debug).toHaveBeenCalledWith(
'UserProfileSettingsClient not set'
);
});
});

View file

@ -1,65 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { CoreContext } from '@kbn/core-base-server-internal';
import { Logger } from '@kbn/logging';
import { KibanaRequest } from '@kbn/core-http-server';
import { DarkModeValue } from '@kbn/core-ui-settings-common';
import { UserProfileSettingsClientContract } from '@kbn/core-user-settings-server';
/**
* @internal
*/
export interface InternalUserSettingsServiceSetup {
setUserProfileSettings: (client: UserProfileSettingsClientContract) => void;
getUserSettingDarkMode: (request: KibanaRequest) => Promise<DarkModeValue | undefined>;
}
export class UserSettingsService {
private logger: Logger;
private client?: UserProfileSettingsClientContract;
constructor(coreContext: CoreContext) {
this.logger = coreContext.logger.get('user-settings-service');
}
public setup(): InternalUserSettingsServiceSetup {
return {
setUserProfileSettings: (client: UserProfileSettingsClientContract) => {
this.client = client;
},
getUserSettingDarkMode: async (request: KibanaRequest) => {
const userSettings = await this.getSettings(request);
return this.getUserSettingDarkMode(userSettings);
},
};
}
private async getSettings(request: KibanaRequest): Promise<Record<string, string>> {
let result = {};
if (this.client) {
result = (await this.client.get(request)) as Record<string, string>;
} else {
this.logger.debug('UserProfileSettingsClient not set');
}
return result;
}
private async getUserSettingDarkMode(
userSettings: Record<string, string>
): Promise<DarkModeValue | undefined> {
let result;
if (userSettings?.darkMode) {
result = userSettings.darkMode.toUpperCase() === 'DARK';
}
return result;
}
}

View file

@ -1,14 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { UserSettingsService } from '@kbn/core-user-settings-server-internal';
export const serviceContractMock = (): jest.Mocked<UserSettingsService> => {
return {
setup: jest.fn(),
} as unknown as jest.Mocked<UserSettingsService>;
};

View file

@ -6,20 +6,25 @@
* Side Public License, v 1.
*/
import { serviceContractMock } from './service_contract.mock';
import type { PublicMethodsOf } from '@kbn/utility-types';
import type {
UserSettingsService,
InternalUserSettingsServiceSetup,
} from '@kbn/core-user-settings-server-internal';
const createSetupContractMock = () => {
const createSetupContractMock = (): jest.Mocked<InternalUserSettingsServiceSetup> => {
return {
setUserProfileSettings: jest.fn(),
getUserSettingDarkMode: jest.fn(),
};
};
const createMock = () => {
const mocked = serviceContractMock();
mocked.setup.mockReturnValue(createSetupContractMock());
// mocked.start.mockReturnValue(createStartContractMock());
return mocked;
const createMock = (): jest.Mocked<PublicMethodsOf<UserSettingsService>> => {
const mock = {
setup: jest.fn(),
start: jest.fn(),
};
mock.setup.mockReturnValue(createSetupContractMock());
return mock;
};
export const userSettingsServiceMock = {

View file

@ -9,6 +9,7 @@
},
"kbn_references": [
"@kbn/core-user-settings-server-internal",
"@kbn/utility-types",
],
"include": [
"**/*.ts",

View file

@ -6,4 +6,4 @@
* Side Public License, v 1.
*/
export type { UserSettingsServiceSetup, UserProfileSettingsClientContract } from './types';
export type { UserSettingsServiceSetup } from './types';

View file

@ -7,7 +7,6 @@
]
},
"kbn_references": [
"@kbn/core-http-server",
],
"include": [
"**/*.ts",

View file

@ -5,13 +5,8 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { KibanaRequest } from '@kbn/core-http-server';
/** @public */
export interface UserSettingsServiceSetup {
setUserProfileSettings: (client: UserProfileSettingsClientContract) => void;
}
export interface UserProfileSettingsClientContract {
get: (request: KibanaRequest) => Promise<Record<string, string>>;
}
// keeping the empty service contract for now as we might re-use it very soon
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface UserSettingsServiceSetup {}

View file

@ -60,9 +60,6 @@ import { setupSpacesClient } from './spaces';
import { registerSecurityUsageCollector } from './usage_collector';
import { UserProfileService } from './user_profile';
import type { UserProfileServiceStartInternal } from './user_profile';
import { UserProfileSettingsClient } from './user_profile/user_profile_settings_client';
import type { UserSettingServiceStart } from './user_profile/user_setting_service';
import { UserSettingService } from './user_profile/user_setting_service';
import type { AuthenticatedUser, SecurityLicense } from '../common';
import { SecurityLicenseService } from '../common/licensing';
@ -172,9 +169,6 @@ export class SecurityPlugin
private readonly userProfileService: UserProfileService;
private userProfileStart?: UserProfileServiceStartInternal;
private readonly userSettingService: UserSettingService;
private userSettingServiceStart?: UserSettingServiceStart;
private userProfileSettingsClient: UserProfileSettingsClient;
private readonly getUserProfileService = () => {
if (!this.userProfileStart) {
throw new Error(`userProfileStart is not registered!`);
@ -202,15 +196,8 @@ export class SecurityPlugin
this.userProfileService = new UserProfileService(
this.initializerContext.logger.get('user-profile')
);
this.userSettingService = new UserSettingService(
this.initializerContext.logger.get('user-settings')
);
this.analyticsService = new AnalyticsService(this.initializerContext.logger.get('analytics'));
this.userProfileSettingsClient = new UserProfileSettingsClient(
this.initializerContext.logger.get('user-settings-client')
);
}
public setup(
@ -238,8 +225,6 @@ export class SecurityPlugin
features: depsServices.features,
}));
core.userSettings.setUserProfileSettings(this.userProfileSettingsClient);
const { license } = this.securityLicenseService.setup({
license$: licensing.license$,
});
@ -386,8 +371,6 @@ export class SecurityPlugin
this.session = session;
this.userProfileStart = this.userProfileService.start({ clusterClient, session });
this.userSettingServiceStart = this.userSettingService.start(this.userProfileStart);
this.userProfileSettingsClient.setUserSettingsServiceStart(this.userSettingServiceStart);
// In serverless, we want to redirect users to the list of projects instead of standard "Logged Out" page.
const customLogoutURL =

View file

@ -1,46 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { loggingSystemMock } from '@kbn/core/server/mocks';
import type { httpServerMock } from '@kbn/core-http-server-mocks';
import type { Logger } from '@kbn/logging';
import { UserProfileSettingsClient } from './user_profile_settings_client';
import type { UserSettingServiceStart } from './user_setting_service';
describe('UserProfileSettingsClient', () => {
let mockRequest: ReturnType<typeof httpServerMock.createKibanaRequest>;
let client: UserProfileSettingsClient;
let logger: Logger;
let userSettingServiceStart: jest.Mocked<UserSettingServiceStart>;
beforeEach(() => {
userSettingServiceStart = {
getCurrentUserProfileSettings: jest.fn(),
};
userSettingServiceStart.getCurrentUserProfileSettings.mockResolvedValue({ darkMode: 'dark' });
logger = loggingSystemMock.createLogger();
client = new UserProfileSettingsClient(logger);
});
describe('#get', () => {
it('should return empty before UserSettingServiceStart is set', async () => {
const userSettings = await client.get(mockRequest);
expect(userSettings).toEqual({});
expect(logger.debug).toHaveBeenCalledWith('UserSettingsServiceStart has not been set yet');
});
it('should return user settings after UserSettingServiceStart is set', async () => {
client.setUserSettingsServiceStart(userSettingServiceStart);
const userSettings = await client.get(mockRequest);
expect(userSettings).toEqual({ darkMode: 'dark' });
});
});
});

View file

@ -1,45 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { Logger } from '@kbn/core/server';
import type { KibanaRequest } from '@kbn/core-http-server';
import type { UserProfileSettingsClientContract } from '@kbn/core-user-settings-server';
import type { UserSettingServiceStart } from './user_setting_service';
/**
* A wrapper client around {@link UserSettingServiceStart} that exposes a method to get the current user's profile
*/
export class UserProfileSettingsClient implements UserProfileSettingsClientContract {
private userSettingServiceStart: UserSettingServiceStart | undefined;
private logger: Logger;
constructor(logger: Logger) {
this.logger = logger;
}
/**
* Returns the current user's user profile settings
*
* @param request the KibanaRequest that is required to get the current user and their settings
* @return the User Settings values retrieved from the UserSettingsServiceStart, if it has been set, otherwise,
* default to an empty Record
*/
async get(request: KibanaRequest): Promise<Record<string, string>> {
let result: Record<string, string> = {} as Record<string, string>;
if (this.userSettingServiceStart) {
result = await this.userSettingServiceStart.getCurrentUserProfileSettings(request);
} else {
this.logger.debug('UserSettingsServiceStart has not been set yet');
}
return result;
}
setUserSettingsServiceStart(userSettingServiceStart: UserSettingServiceStart) {
this.userSettingServiceStart = userSettingServiceStart;
}
}

View file

@ -1,55 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { KibanaRequest } from '@kbn/core-http-server';
import type { Logger } from '@kbn/logging';
import type {
UserProfileGetCurrentParams,
UserProfileServiceStart,
} from '@kbn/security-plugin-types-server';
export interface UserSettingServiceStart {
/**
* Returns the currently signed-in user's settings from their User Profile
*
* @param request the KibanaRequest that is required to get the current user and their settings
*/
getCurrentUserProfileSettings(request: KibanaRequest): Promise<Record<string, string>>;
}
/**
* A service that wraps the {@link UserProfileServiceStart} so that only the 'getCurrent' method is made available
*/
export class UserSettingService {
private readonly logger: Logger;
constructor(logger: Logger) {
this.logger = logger;
}
start(userProfileServiceStart: UserProfileServiceStart): UserSettingServiceStart {
return {
getCurrentUserProfileSettings: async (request) => {
const params: UserProfileGetCurrentParams = {
request,
dataPath: 'userSettings',
};
const currentUserProfile = await userProfileServiceStart.getCurrent(params);
let result = {} as Record<string, string>;
if (currentUserProfile?.data?.userSettings) {
result = currentUserProfile?.data?.userSettings as Record<string, string>;
} else {
this.logger.debug('User Settings not found.');
}
return result;
},
};
}
}

View file

@ -1,143 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { SecurityGetUserProfileResponse } from '@elastic/elasticsearch/lib/api/types';
import {
elasticsearchServiceMock,
httpServerMock,
loggingSystemMock,
} from '@kbn/core/server/mocks';
import type { UserProfileServiceStart } from '@kbn/security-plugin-types-server';
import { UserProfileService } from './user_profile_service';
import { UserSettingService } from './user_setting_service';
import type { UserProfileWithSecurity } from '../../common';
import { licenseMock } from '../../common/licensing/index.mock';
import { userProfileMock } from '../../common/model/user_profile.mock';
import { authorizationMock } from '../authorization/index.mock';
import { sessionMock } from '../session_management/session.mock';
const logger = loggingSystemMock.createLogger();
describe('UserSettingService', () => {
let mockStartParams: {
clusterClient: ReturnType<typeof elasticsearchServiceMock.createClusterClient>;
session: ReturnType<typeof sessionMock.create>;
};
let mockAuthz: ReturnType<typeof authorizationMock.create>;
let userProfileService: UserProfileService;
let userSettingsService: UserSettingService;
let userProfileServiceStart: UserProfileServiceStart;
beforeEach(() => {
mockStartParams = {
clusterClient: elasticsearchServiceMock.createClusterClient(),
session: sessionMock.create(),
};
mockAuthz = authorizationMock.create();
userProfileService = new UserProfileService(logger);
userSettingsService = new UserSettingService(logger);
userProfileService.setup({
authz: mockAuthz,
license: licenseMock.create({ allowUserProfileCollaboration: true }),
});
userProfileServiceStart = userProfileService.start(mockStartParams);
});
afterEach(() => {
logger.error.mockClear();
});
it('should expose correct start contract', () => {
const userSettingServiceStart = userSettingsService.start(userProfileServiceStart);
expect(userSettingServiceStart).toMatchInlineSnapshot(`
Object {
"getCurrentUserProfileSettings": [Function],
}
`);
});
describe('#getCurrentUserProfileSettings', () => {
let mockUserProfile: UserProfileWithSecurity;
let mockRequest: ReturnType<typeof httpServerMock.createKibanaRequest>;
beforeEach(() => {
mockRequest = httpServerMock.createKibanaRequest();
});
it('returns user settings data', async () => {
mockUserProfile = userProfileMock.createWithSecurity({
uid: 'UID',
user: {
username: 'user-1',
full_name: 'full-name-1',
realm_name: 'some-realm',
realm_domain: 'some-domain',
roles: ['role-1'],
},
data: {
kibana: {
userSettings: {
darkMode: 'dark',
},
},
},
});
mockStartParams.clusterClient.asInternalUser.security.getUserProfile.mockResolvedValue({
profiles: [mockUserProfile],
} as unknown as SecurityGetUserProfileResponse);
mockStartParams.session.get.mockResolvedValue({
error: null,
value: sessionMock.createValue({ userProfileId: mockUserProfile.uid }),
});
userProfileServiceStart = userProfileService.start(mockStartParams);
const userSettingServiceStart = userSettingsService.start(userProfileServiceStart);
await expect(
userSettingServiceStart.getCurrentUserProfileSettings(mockRequest)
).resolves.toEqual({ darkMode: 'dark' });
});
it('logs a warning and returns ', async () => {
mockUserProfile = userProfileMock.createWithSecurity({
uid: 'UID',
user: {
username: 'user-1',
full_name: 'full-name-1',
realm_name: 'some-realm',
realm_domain: 'some-domain',
roles: ['role-1'],
},
data: {},
});
mockStartParams.clusterClient.asInternalUser.security.getUserProfile.mockResolvedValue({
profiles: [mockUserProfile],
} as unknown as SecurityGetUserProfileResponse);
mockStartParams.session.get.mockResolvedValue({
error: null,
value: sessionMock.createValue({ userProfileId: mockUserProfile.uid }),
});
userProfileServiceStart = userProfileService.start(mockStartParams);
const userSettingServiceStart = userSettingsService.start(userProfileServiceStart);
await expect(
userSettingServiceStart.getCurrentUserProfileSettings(mockRequest)
).resolves.toEqual({});
expect(logger.debug).toHaveBeenCalledWith('User Settings not found.');
});
});
});

View file

@ -64,7 +64,6 @@
"@kbn/shared-ux-router",
"@kbn/core-http-server",
"@kbn/core-http-server-mocks",
"@kbn/core-user-settings-server",
"@kbn/remote-clusters-plugin",
"@kbn/analytics-client",
"@kbn/security-plugin-types-common",