Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down
1 change: 1 addition & 0 deletions packages/core/root/core-root-server-internal/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Original file line number Diff line number Diff line change
@@ -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');
});
});
Original file line number Diff line number Diff line change
@@ -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;
Comment on lines +31 to +33
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, this is not a new file, it was moved from packages/core/user-settings/core-user-settings-server-internal/user_settings_service.ts, but I guess the file changed too much so it lost the info


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;
};
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down

This file was deleted.

Loading