mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Fleet Plugin] Use server-side authc.getCurrentUser from core.security (#186932)
Part of https://github.com/elastic/kibana/issues/186574 Background: This PR serves as an example of a plugin migrating away from depending on the Security plugin, which is a high priority effort for the last release before 9.0. The Fleet plugin uses the `authc.getCurrentUser` in server-side code, and they are addressed in this PR. It also uses `authc.apiKeys` in a few areas, but that isn't ready to be migrated yet. ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
3d99878c96
commit
55bbd76fce
15 changed files with 56 additions and 45 deletions
|
@ -12,6 +12,7 @@ import {
|
|||
loggingSystemMock,
|
||||
savedObjectsClientMock,
|
||||
savedObjectsServiceMock,
|
||||
securityServiceMock,
|
||||
} from '@kbn/core/server/mocks';
|
||||
import { dataPluginMock } from '@kbn/data-plugin/server/mocks';
|
||||
import { licensingMock } from '@kbn/licensing-plugin/server/mocks';
|
||||
|
@ -50,6 +51,7 @@ export interface MockedFleetAppContext extends FleetAppContext {
|
|||
data: ReturnType<typeof dataPluginMock.createStartContract>;
|
||||
encryptedSavedObjectsStart?: ReturnType<typeof encryptedSavedObjectsMock.createStart>;
|
||||
savedObjects: ReturnType<typeof savedObjectsServiceMock.createStartContract>;
|
||||
securityCoreStart: ReturnType<typeof securityServiceMock.createStart>;
|
||||
securitySetup: ReturnType<typeof securityMock.createSetup>;
|
||||
securityStart: ReturnType<typeof securityMock.createStart>;
|
||||
logger: ReturnType<ReturnType<typeof loggingSystemMock.create>['get']>;
|
||||
|
@ -74,6 +76,7 @@ export const createAppContextStartContractMock = (
|
|||
encryptedSavedObjectsStart: encryptedSavedObjectsMock.createStart(),
|
||||
encryptedSavedObjectsSetup: encryptedSavedObjectsMock.createSetup({ canEncrypt: true }),
|
||||
savedObjects: savedObjectsServiceMock.createStartContract(),
|
||||
securityCoreStart: securityServiceMock.createStart(),
|
||||
securitySetup: securityMock.createSetup(),
|
||||
securityStart: securityMock.createStart(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
|
|
|
@ -23,6 +23,7 @@ import type {
|
|||
PluginInitializerContext,
|
||||
SavedObjectsClientContract,
|
||||
SavedObjectsServiceStart,
|
||||
SecurityServiceStart,
|
||||
ServiceStatus,
|
||||
} from '@kbn/core/server';
|
||||
import { DEFAULT_APP_CATEGORIES, SavedObjectsClient, ServiceStatusLevels } from '@kbn/core/server';
|
||||
|
@ -155,6 +156,7 @@ export interface FleetAppContext {
|
|||
data: DataPluginStart;
|
||||
encryptedSavedObjectsStart?: EncryptedSavedObjectsPluginStart;
|
||||
encryptedSavedObjectsSetup?: EncryptedSavedObjectsPluginSetup;
|
||||
securityCoreStart: SecurityServiceStart;
|
||||
securitySetup: SecurityPluginSetup;
|
||||
securityStart: SecurityPluginStart;
|
||||
config$?: Observable<FleetConfigType>;
|
||||
|
@ -613,6 +615,7 @@ export class FleetPlugin
|
|||
data: plugins.data,
|
||||
encryptedSavedObjectsStart: plugins.encryptedSavedObjects,
|
||||
encryptedSavedObjectsSetup: this.encryptedSavedObjectsSetup,
|
||||
securityCoreStart: core.security,
|
||||
securitySetup: this.securitySetup,
|
||||
securityStart: plugins.security,
|
||||
configInitialValue: this.configInitialValue,
|
||||
|
|
|
@ -215,7 +215,7 @@ export const createAgentPolicyHandler: FleetRequestHandler<
|
|||
const fleetContext = await context.fleet;
|
||||
const soClient = fleetContext.internalSoClient;
|
||||
const esClient = coreContext.elasticsearch.client.asInternalUser;
|
||||
const user = (await appContextService.getSecurity()?.authc.getCurrentUser(request)) || undefined;
|
||||
const user = appContextService.getSecurityCore().authc.getCurrentUser(request) || undefined;
|
||||
const withSysMonitoring = request.query.sys_monitoring ?? false;
|
||||
const monitoringEnabled = request.body.monitoring_enabled;
|
||||
const { has_fleet_server: hasFleetServer, force, ...newPolicy } = request.body;
|
||||
|
@ -261,7 +261,7 @@ export const updateAgentPolicyHandler: FleetRequestHandler<
|
|||
const fleetContext = await context.fleet;
|
||||
const soClient = coreContext.savedObjects.client;
|
||||
const esClient = coreContext.elasticsearch.client.asInternalUser;
|
||||
const user = await appContextService.getSecurity()?.authc.getCurrentUser(request);
|
||||
const user = appContextService.getSecurityCore().authc.getCurrentUser(request) || undefined;
|
||||
const { force, ...data } = request.body;
|
||||
|
||||
const spaceId = fleetContext.spaceId;
|
||||
|
@ -271,11 +271,7 @@ export const updateAgentPolicyHandler: FleetRequestHandler<
|
|||
esClient,
|
||||
request.params.agentPolicyId,
|
||||
data,
|
||||
{
|
||||
force,
|
||||
user: user || undefined,
|
||||
spaceId,
|
||||
}
|
||||
{ force, user, spaceId }
|
||||
);
|
||||
const body: UpdateAgentPolicyResponse = { item: agentPolicy };
|
||||
return response.ok({
|
||||
|
@ -300,16 +296,14 @@ export const copyAgentPolicyHandler: RequestHandler<
|
|||
const coreContext = await context.core;
|
||||
const soClient = coreContext.savedObjects.client;
|
||||
const esClient = coreContext.elasticsearch.client.asInternalUser;
|
||||
const user = await appContextService.getSecurity()?.authc.getCurrentUser(request);
|
||||
const user = appContextService.getSecurityCore().authc.getCurrentUser(request) || undefined;
|
||||
try {
|
||||
const agentPolicy = await agentPolicyService.copy(
|
||||
soClient,
|
||||
esClient,
|
||||
request.params.agentPolicyId,
|
||||
request.body,
|
||||
{
|
||||
user: user || undefined,
|
||||
}
|
||||
{ user }
|
||||
);
|
||||
|
||||
const body: CopyAgentPolicyResponse = { item: agentPolicy };
|
||||
|
@ -329,16 +323,13 @@ export const deleteAgentPoliciesHandler: RequestHandler<
|
|||
const coreContext = await context.core;
|
||||
const soClient = coreContext.savedObjects.client;
|
||||
const esClient = coreContext.elasticsearch.client.asInternalUser;
|
||||
const user = await appContextService.getSecurity()?.authc.getCurrentUser(request);
|
||||
const user = appContextService.getSecurityCore().authc.getCurrentUser(request) || undefined;
|
||||
try {
|
||||
const body: DeleteAgentPolicyResponse = await agentPolicyService.delete(
|
||||
soClient,
|
||||
esClient,
|
||||
request.body.agentPolicyId,
|
||||
{
|
||||
user: user || undefined,
|
||||
force: request.body.force,
|
||||
}
|
||||
{ user, force: request.body.force }
|
||||
);
|
||||
return response.ok({
|
||||
body,
|
||||
|
|
|
@ -307,7 +307,7 @@ export const installPackageFromRegistryHandler: FleetRequestHandler<
|
|||
const fleetContext = await context.fleet;
|
||||
const savedObjectsClient = fleetContext.internalSoClient;
|
||||
const esClient = coreContext.elasticsearch.client.asInternalUser;
|
||||
const user = (await appContextService.getSecurity()?.authc.getCurrentUser(request)) || undefined;
|
||||
const user = appContextService.getSecurityCore().authc.getCurrentUser(request) || undefined;
|
||||
|
||||
const { pkgName, pkgVersion } = request.params;
|
||||
|
||||
|
@ -350,7 +350,7 @@ export const createCustomIntegrationHandler: FleetRequestHandler<
|
|||
const fleetContext = await context.fleet;
|
||||
const savedObjectsClient = fleetContext.internalSoClient;
|
||||
const esClient = coreContext.elasticsearch.client.asInternalUser;
|
||||
const user = (await appContextService.getSecurity()?.authc.getCurrentUser(request)) || undefined;
|
||||
const user = appContextService.getSecurityCore().authc.getCurrentUser(request) || undefined;
|
||||
const kibanaVersion = appContextService.getKibanaVersion();
|
||||
const authorizationHeader = HTTPAuthorizationHeader.parseFromRequest(request, user?.username);
|
||||
const spaceId = fleetContext.spaceId;
|
||||
|
@ -425,7 +425,7 @@ export const bulkInstallPackagesFromRegistryHandler: FleetRequestHandler<
|
|||
const savedObjectsClient = fleetContext.internalSoClient;
|
||||
const esClient = coreContext.elasticsearch.client.asInternalUser;
|
||||
const spaceId = fleetContext.spaceId;
|
||||
const user = (await appContextService.getSecurity()?.authc.getCurrentUser(request)) || undefined;
|
||||
const user = appContextService.getSecurityCore().authc.getCurrentUser(request) || undefined;
|
||||
const authorizationHeader = HTTPAuthorizationHeader.parseFromRequest(request, user?.username);
|
||||
|
||||
const bulkInstalledResponses = await bulkInstallPackages({
|
||||
|
@ -457,7 +457,7 @@ export const installPackageByUploadHandler: FleetRequestHandler<
|
|||
const contentType = request.headers['content-type'] as string; // from types it could also be string[] or undefined but this is checked later
|
||||
const archiveBuffer = Buffer.from(request.body);
|
||||
const spaceId = fleetContext.spaceId;
|
||||
const user = (await appContextService.getSecurity()?.authc.getCurrentUser(request)) || undefined;
|
||||
const user = appContextService.getSecurityCore().authc.getCurrentUser(request) || undefined;
|
||||
const authorizationHeader = HTTPAuthorizationHeader.parseFromRequest(request, user?.username);
|
||||
|
||||
const res = await installPackage({
|
||||
|
@ -561,7 +561,7 @@ export const reauthorizeTransformsHandler: FleetRequestHandler<
|
|||
|
||||
let username;
|
||||
try {
|
||||
const user = await appContextService.getSecurity()?.authc.getCurrentUser(request);
|
||||
const user = appContextService.getSecurityCore().authc.getCurrentUser(request);
|
||||
if (user) {
|
||||
username = user.username;
|
||||
}
|
||||
|
|
|
@ -231,7 +231,7 @@ export const createPackagePolicyHandler: FleetRequestHandler<
|
|||
const fleetContext = await context.fleet;
|
||||
const soClient = fleetContext.internalSoClient;
|
||||
const esClient = coreContext.elasticsearch.client.asInternalUser;
|
||||
const user = appContextService.getSecurity()?.authc.getCurrentUser(request) || undefined;
|
||||
const user = appContextService.getSecurityCore().authc.getCurrentUser(request) || undefined;
|
||||
const { force, id, package: pkg, ...newPolicy } = request.body;
|
||||
const authorizationHeader = HTTPAuthorizationHeader.parseFromRequest(request, user?.username);
|
||||
let wasPackageAlreadyInstalled = false;
|
||||
|
@ -339,7 +339,7 @@ export const updatePackagePolicyHandler: FleetRequestHandler<
|
|||
const soClient = fleetContext.internalSoClient;
|
||||
const limitedToPackages = fleetContext.limitedToPackages;
|
||||
const esClient = coreContext.elasticsearch.client.asInternalUser;
|
||||
const user = appContextService.getSecurity()?.authc.getCurrentUser(request) || undefined;
|
||||
const user = appContextService.getSecurityCore().authc.getCurrentUser(request) || undefined;
|
||||
const packagePolicy = await packagePolicyService.get(soClient, request.params.packagePolicyId);
|
||||
|
||||
if (!packagePolicy) {
|
||||
|
@ -442,7 +442,7 @@ export const deletePackagePolicyHandler: RequestHandler<
|
|||
const coreContext = await context.core;
|
||||
const soClient = coreContext.savedObjects.client;
|
||||
const esClient = coreContext.elasticsearch.client.asInternalUser;
|
||||
const user = appContextService.getSecurity()?.authc.getCurrentUser(request) || undefined;
|
||||
const user = appContextService.getSecurityCore().authc.getCurrentUser(request) || undefined;
|
||||
|
||||
try {
|
||||
const body: PostDeletePackagePoliciesResponse = await packagePolicyService.delete(
|
||||
|
@ -470,7 +470,7 @@ export const deleteOnePackagePolicyHandler: RequestHandler<
|
|||
const coreContext = await context.core;
|
||||
const soClient = coreContext.savedObjects.client;
|
||||
const esClient = coreContext.elasticsearch.client.asInternalUser;
|
||||
const user = appContextService.getSecurity()?.authc.getCurrentUser(request) || undefined;
|
||||
const user = appContextService.getSecurityCore().authc.getCurrentUser(request) || undefined;
|
||||
|
||||
try {
|
||||
const res = await packagePolicyService.delete(
|
||||
|
@ -509,7 +509,7 @@ export const upgradePackagePolicyHandler: RequestHandler<
|
|||
const coreContext = await context.core;
|
||||
const soClient = coreContext.savedObjects.client;
|
||||
const esClient = coreContext.elasticsearch.client.asInternalUser;
|
||||
const user = appContextService.getSecurity()?.authc.getCurrentUser(request) || undefined;
|
||||
const user = appContextService.getSecurityCore().authc.getCurrentUser(request) || undefined;
|
||||
try {
|
||||
const body: UpgradePackagePolicyResponse = await packagePolicyService.upgrade(
|
||||
soClient,
|
||||
|
|
|
@ -49,13 +49,11 @@ export const putSettingsHandler: FleetRequestHandler<
|
|||
> = async (context, request, response) => {
|
||||
const soClient = (await context.fleet).internalSoClient;
|
||||
const esClient = (await context.core).elasticsearch.client.asInternalUser;
|
||||
const user = await appContextService.getSecurity()?.authc.getCurrentUser(request);
|
||||
const user = appContextService.getSecurityCore().authc.getCurrentUser(request) || undefined;
|
||||
|
||||
try {
|
||||
const settings = await settingsService.saveSettings(soClient, request.body);
|
||||
await agentPolicyService.bumpAllAgentPolicies(esClient, {
|
||||
user: user || undefined,
|
||||
});
|
||||
await agentPolicyService.bumpAllAgentPolicies(esClient, { user });
|
||||
const body = {
|
||||
item: settings,
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@ import { safeDump } from 'js-yaml';
|
|||
import pMap from 'p-map';
|
||||
import { lt } from 'semver';
|
||||
import type {
|
||||
AuthenticatedUser,
|
||||
ElasticsearchClient,
|
||||
SavedObjectsBulkUpdateObject,
|
||||
SavedObjectsBulkUpdateResponse,
|
||||
|
@ -20,7 +21,6 @@ import type {
|
|||
} from '@kbn/core/server';
|
||||
import { SavedObjectsUtils } from '@kbn/core/server';
|
||||
|
||||
import type { AuthenticatedUser } from '@kbn/security-plugin/server';
|
||||
import type { BulkResponseItem } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
|
||||
import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common/constants';
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server';
|
||||
|
||||
import type { AuthenticatedUser } from '@kbn/security-plugin/common';
|
||||
import type {
|
||||
AuthenticatedUser,
|
||||
ElasticsearchClient,
|
||||
SavedObjectsClientContract,
|
||||
} from '@kbn/core/server';
|
||||
|
||||
import type { HTTPAuthorizationHeader } from '../../common/http_authorization_header';
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import type {
|
|||
HttpServiceSetup,
|
||||
Logger,
|
||||
KibanaRequest,
|
||||
SecurityServiceStart,
|
||||
} from '@kbn/core/server';
|
||||
|
||||
import { CoreKibanaRequest } from '@kbn/core/server';
|
||||
|
@ -61,6 +62,7 @@ class AppContextService {
|
|||
private data: DataPluginStart | undefined;
|
||||
private esClient: ElasticsearchClient | undefined;
|
||||
private experimentalFeatures?: ExperimentalFeatures;
|
||||
private securityCoreStart: SecurityServiceStart | undefined;
|
||||
private securitySetup: SecurityPluginSetup | undefined;
|
||||
private securityStart: SecurityPluginStart | undefined;
|
||||
private config$?: Observable<FleetConfigType>;
|
||||
|
@ -86,6 +88,7 @@ class AppContextService {
|
|||
this.encryptedSavedObjectsStart = appContext.encryptedSavedObjectsStart;
|
||||
this.encryptedSavedObjects = appContext.encryptedSavedObjectsStart?.getClient();
|
||||
this.encryptedSavedObjectsSetup = appContext.encryptedSavedObjectsSetup;
|
||||
this.securityCoreStart = appContext.securityCoreStart;
|
||||
this.securitySetup = appContext.securitySetup;
|
||||
this.securityStart = appContext.securityStart;
|
||||
this.savedObjects = appContext.savedObjects;
|
||||
|
@ -129,6 +132,10 @@ class AppContextService {
|
|||
return this.encryptedSavedObjects;
|
||||
}
|
||||
|
||||
public getSecurityCore() {
|
||||
return this.securityCoreStart!;
|
||||
}
|
||||
|
||||
public getSecurity() {
|
||||
return this.securityStart!;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import semverLt from 'semver/functions/lt';
|
||||
import { getFlattenedObject } from '@kbn/std';
|
||||
import type {
|
||||
AuthenticatedUser,
|
||||
KibanaRequest,
|
||||
ElasticsearchClient,
|
||||
SavedObjectsClientContract,
|
||||
|
@ -25,8 +26,6 @@ import { safeLoad } from 'js-yaml';
|
|||
|
||||
import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common/constants';
|
||||
|
||||
import { type AuthenticatedUser } from '@kbn/security-plugin/server';
|
||||
|
||||
import pMap from 'p-map';
|
||||
|
||||
import type { SavedObjectError } from '@kbn/core-saved-objects-common';
|
||||
|
|
|
@ -5,9 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { KibanaRequest, Logger, RequestHandlerContext } from '@kbn/core/server';
|
||||
import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server';
|
||||
import type { AuthenticatedUser } from '@kbn/security-plugin/server';
|
||||
import type {
|
||||
AuthenticatedUser,
|
||||
KibanaRequest,
|
||||
Logger,
|
||||
RequestHandlerContext,
|
||||
ElasticsearchClient,
|
||||
SavedObjectsClientContract,
|
||||
} from '@kbn/core/server';
|
||||
|
||||
import type { SavedObjectError } from '@kbn/core-saved-objects-common';
|
||||
|
||||
|
|
|
@ -10,12 +10,10 @@ import type {
|
|||
CheckPrivilegesResponse,
|
||||
CheckPrivilegesPayload,
|
||||
} from '@kbn/security-plugin/server';
|
||||
import type { RequestHandler } from '@kbn/core/server';
|
||||
import type { AuthenticatedUser, RequestHandler } from '@kbn/core/server';
|
||||
import type { VersionedRouter } from '@kbn/core-http-server';
|
||||
import { loggingSystemMock } from '@kbn/core/server/mocks';
|
||||
|
||||
import type { AuthenticatedUser } from '@kbn/security-plugin/common';
|
||||
|
||||
import { coreMock } from '@kbn/core/server/mocks';
|
||||
|
||||
import { API_VERSIONS } from '../../../common/constants';
|
||||
|
@ -85,7 +83,7 @@ describe('FleetAuthzRouter', () => {
|
|||
// @ts-expect-error type doesn't properly respect deeply mocked keys
|
||||
mockContext.securityStart.authz.actions.ui.get.mockImplementation((priv) => `ui:${priv}`);
|
||||
|
||||
mockContext.securityStart.authc.getCurrentUser.mockReturnValue({
|
||||
mockContext.securityCoreStart.authc.getCurrentUser.mockReturnValue({
|
||||
username: 'foo',
|
||||
roles,
|
||||
} as unknown as AuthenticatedUser);
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
import { deepFreeze } from '@kbn/std';
|
||||
import type { SecurityPluginStart, CheckPrivilegesDynamically } from '@kbn/security-plugin/server';
|
||||
|
||||
import { securityServiceMock, type SecurityStartMock } from '@kbn/core-security-server-mocks';
|
||||
|
||||
import { appContextService } from '../app_context';
|
||||
import type { FleetAuthz } from '../../../common';
|
||||
|
||||
|
@ -554,12 +556,13 @@ describe('When using calculateRouteAuthz()', () => {
|
|||
});
|
||||
|
||||
describe('getAuthzFromRequest', () => {
|
||||
let mockSecurityCore: SecurityStartMock;
|
||||
let mockSecurity: jest.MockedObjectDeep<SecurityPluginStart>;
|
||||
let checkPrivileges: jest.MockedFn<CheckPrivilegesDynamically>;
|
||||
beforeEach(() => {
|
||||
checkPrivileges = jest.fn();
|
||||
mockSecurityCore = securityServiceMock.createStart();
|
||||
mockSecurity = {
|
||||
authc: { getCurrentUser: jest.fn() },
|
||||
authz: {
|
||||
checkPrivilegesDynamicallyWithRequest: jest.fn().mockReturnValue(checkPrivileges),
|
||||
actions: {
|
||||
|
@ -576,6 +579,7 @@ describe('getAuthzFromRequest', () => {
|
|||
},
|
||||
} as unknown as jest.MockedObjectDeep<SecurityPluginStart>;
|
||||
|
||||
jest.mocked(appContextService.getSecurityCore).mockReturnValue(mockSecurityCore);
|
||||
jest.mocked(appContextService.getSecurity).mockReturnValue(mockSecurity);
|
||||
jest.mocked(appContextService.getSecurityLicense).mockReturnValue({
|
||||
isEnabled: () => true,
|
||||
|
|
|
@ -45,7 +45,7 @@ export function checkSuperuser(req: KibanaRequest) {
|
|||
return false;
|
||||
}
|
||||
|
||||
const security = appContextService.getSecurity();
|
||||
const security = appContextService.getSecurityCore();
|
||||
const user = security.authc.getCurrentUser(req);
|
||||
|
||||
if (!user) {
|
||||
|
|
|
@ -111,5 +111,6 @@
|
|||
"@kbn/test-jest-helpers",
|
||||
"@kbn/core-saved-objects-utils-server",
|
||||
"@kbn/integration-assistant-plugin",
|
||||
"@kbn/core-security-server-mocks",
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue