[Fleet] prep for package level rbac (#140458)

* [Fleet] prep for package level rbac
This commit is contained in:
Joey F. Poon 2022-09-14 08:35:56 -05:00 committed by GitHub
parent 0c8dd665ce
commit 9c96a092dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 345 additions and 204 deletions

View file

@ -7,7 +7,7 @@
import { uniq, map } from 'lodash';
import type { SavedObjectsClientContract } from '@kbn/core/server';
import type {
PackagePolicyServiceInterface,
PackagePolicyClient,
AgentPolicyServiceInterface,
AgentService,
} from '@kbn/fleet-plugin/server';
@ -65,7 +65,7 @@ export const getCspAgentPolicies = async (
export const getCspPackagePolicies = (
soClient: SavedObjectsClientContract,
packagePolicyService: PackagePolicyServiceInterface,
packagePolicyService: PackagePolicyClient,
packageName: string,
queryParams: Partial<BenchmarksQueryParams>
): Promise<ListResult<PackagePolicy>> => {

View file

@ -15,7 +15,7 @@ import {
SavedObjectsErrorHelpers,
} from '@kbn/core/server';
import { transformError } from '@kbn/securitysolution-es-utils';
import type { PackagePolicyServiceInterface } from '@kbn/fleet-plugin/server';
import type { PackagePolicyClient } from '@kbn/fleet-plugin/server';
import type { AuthenticatedUser } from '@kbn/security-plugin/common';
import { unset } from 'lodash';
import produce from 'immer';
@ -147,7 +147,7 @@ export const updatePackagePolicyRuntimeCfgVar = async ({
user,
rules,
}: {
packagePolicyService: PackagePolicyServiceInterface;
packagePolicyService: PackagePolicyClient;
packagePolicy: PackagePolicy;
esClient: ElasticsearchClient;
soClient: SavedObjectsClientContract;

View file

@ -13,7 +13,7 @@ import {
AgentPolicyServiceInterface,
AgentService,
PackageClient,
PackagePolicyServiceInterface,
PackagePolicyClient,
PackageService,
} from '@kbn/fleet-plugin/server';
import {
@ -58,7 +58,7 @@ const mockLatestCspPackageInfo: RegistryPackage = {
describe('CspSetupStatus route', () => {
const router = httpServiceMock.createRouter();
let mockContext: ReturnType<typeof createCspRequestHandlerContextMock>;
let mockPackagePolicyService: jest.Mocked<PackagePolicyServiceInterface>;
let mockPackagePolicyService: jest.Mocked<PackagePolicyClient>;
let mockAgentPolicyService: jest.Mocked<AgentPolicyServiceInterface>;
let mockAgentService: jest.Mocked<AgentService>;
let mockAgentClient: jest.Mocked<AgentClient>;

View file

@ -27,7 +27,7 @@ import type {
AgentService,
PackageService,
AgentPolicyServiceInterface,
PackagePolicyServiceInterface,
PackagePolicyClient,
} from '@kbn/fleet-plugin/server';
import type { FleetStartContract, FleetRequestHandlerContext } from '@kbn/fleet-plugin/server';
import { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server';
@ -64,7 +64,7 @@ export interface CspApiRequestHandlerContext {
soClient: SavedObjectsClientContract;
agentPolicyService: AgentPolicyServiceInterface;
agentService: AgentService;
packagePolicyService: PackagePolicyServiceInterface;
packagePolicyService: PackagePolicyClient;
packageService: PackageService;
}

View file

@ -30,6 +30,7 @@ import {
RegistryResponseError,
PackageFailedVerificationError,
PackagePolicyNotFoundError,
FleetUnauthorizedError,
} from '.';
type IngestErrorHandler = (
@ -74,6 +75,9 @@ const getHTTPResponseCode = (error: IngestManagerError): number => {
if (error instanceof AgentActionNotFoundError) {
return 404;
}
if (error instanceof FleetUnauthorizedError) {
return 403; // Unauthorized
}
return 400; // Bad Request
};

View file

@ -35,7 +35,7 @@ export { AgentNotFoundError, FleetUnauthorizedError } from './errors';
export { config } from './config';
export type { FleetConfigType } from './config';
export type { PackagePolicyServiceInterface } from './services/package_policy';
export type { PackagePolicyClient } from './services/package_policy_service';
export { relativeDownloadUrlFromArtifact } from './services/artifacts/mappings';

View file

@ -18,7 +18,7 @@ import { licensingMock } from '@kbn/licensing-plugin/server/mocks';
import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks';
import { securityMock } from '@kbn/security-plugin/server/mocks';
import type { PackagePolicyServiceInterface } from '../services/package_policy';
import type { PackagePolicyClient } from '../services/package_policy_service';
import type { AgentPolicyServiceInterface } from '../services';
import type { FleetAppContext } from '../plugin';
import { createMockTelemetryEventsSender } from '../telemetry/__mocks__';
@ -86,6 +86,10 @@ export const createFleetRequestHandlerContextMock = (): jest.Mocked<
asCurrentUser: agentServiceMock.createClient(),
asInternalUser: agentServiceMock.createClient(),
},
packagePolicyService: {
asCurrentUser: createPackagePolicyServiceMock(),
asInternalUser: createPackagePolicyServiceMock(),
},
epm: {
internalSoClient: savedObjectsClientMock.create(),
},
@ -105,7 +109,7 @@ export const xpackMocks = {
createRequestHandlerContext: createCoreRequestHandlerContextMock,
};
export const createPackagePolicyServiceMock = (): jest.Mocked<PackagePolicyServiceInterface> => {
export const createPackagePolicyServiceMock = (): jest.Mocked<PackagePolicyClient> => {
return {
buildPackagePolicyFromPackage: jest.fn(),
bulkCreate: jest.fn(),

View file

@ -105,6 +105,8 @@ import type { FleetRouter } from './types/request_context';
import { TelemetryEventsSender } from './telemetry/sender';
import { setupFleet } from './services/setup';
import { BulkActionsResolver } from './services/agents';
import type { PackagePolicyService } from './services/package_policy_service';
import { PackagePolicyServiceImpl } from './services/package_policy';
export interface FleetSetupDeps {
security: SecurityPluginSetup;
@ -215,6 +217,7 @@ export class FleetPlugin
private agentService?: AgentService;
private packageService?: PackageService;
private packagePolicyService?: PackagePolicyService;
constructor(private readonly initializerContext: PluginInitializerContext) {
this.config$ = this.initializerContext.config.create<FleetConfigType>();
@ -327,6 +330,7 @@ export class FleetPlugin
ui: ['read'],
},
},
subFeatures: [],
});
}
@ -345,6 +349,14 @@ export class FleetPlugin
asInternalUser: agentService.asInternalUser,
};
},
get packagePolicyService() {
const service = plugin.setupPackagePolicyService();
return {
asCurrentUser: service.asScoped(request),
asInternalUser: service.asInternalUser,
};
},
authz: await getAuthzFromRequest(request),
epm: {
// Use a lazy getter to avoid constructing this client when not used by a request handler
@ -521,6 +533,14 @@ export class FleetPlugin
return this.agentService;
}
private setupPackagePolicyService(): PackagePolicyService {
if (this.packagePolicyService) {
return this.packagePolicyService;
}
this.packagePolicyService = new PackagePolicyServiceImpl();
return this.packagePolicyService;
}
private setupPackageService(
internalEsClient: ElasticsearchClient,
internalSoClient: SavedObjectsClientContract

View file

@ -13,7 +13,7 @@ import { PACKAGE_POLICY_API_ROUTES } from '../../../common/constants';
import { appContextService, packagePolicyService } from '../../services';
import { createAppContextStartContractMock, xpackMocks } from '../../mocks';
import type {
PackagePolicyServiceInterface,
PackagePolicyClient,
PostPackagePolicyCreateCallback,
PutPackagePolicyUpdateCallback,
FleetRequestHandlerContext,
@ -28,12 +28,12 @@ import type { PackagePolicy } from '../../types';
import { registerRoutes } from '.';
const packagePolicyServiceMock = packagePolicyService as jest.Mocked<PackagePolicyServiceInterface>;
const packagePolicyServiceMock = packagePolicyService as jest.Mocked<PackagePolicyClient>;
jest.mock(
'../../services/package_policy',
(): {
packagePolicyService: jest.Mocked<PackagePolicyServiceInterface>;
packagePolicyService: jest.Mocked<PackagePolicyClient>;
} => {
return {
packagePolicyService: {
@ -95,15 +95,18 @@ describe('When calling package policy', () => {
let routeConfig: RouteConfig<any, any, any, any>;
let context: FleetRequestHandlerContext;
let response: ReturnType<typeof httpServerMock.createResponseFactory>;
let packagePolicyServiceWithAuthzMock: jest.Mocked<PackagePolicyClient>;
beforeEach(() => {
routerMock = httpServiceMock.createRouter() as unknown as jest.Mocked<FleetAuthzRouter>;
registerRoutes(routerMock);
});
beforeEach(() => {
beforeEach(async () => {
appContextService.start(createAppContextStartContractMock());
context = xpackMocks.createRequestHandlerContext() as unknown as FleetRequestHandlerContext;
packagePolicyServiceWithAuthzMock = (await context.fleet).packagePolicyService
.asCurrentUser as jest.Mocked<PackagePolicyClient>;
response = httpServerMock.createResponseFactory();
});
@ -231,7 +234,7 @@ describe('When calling package policy', () => {
await routeHandler(context, request, response);
expect(response.ok).toHaveBeenCalled();
expect(packagePolicyServiceMock.create.mock.calls[0][2]).toEqual({
expect(packagePolicyServiceWithAuthzMock.create.mock.calls[0][2]).toEqual({
policy_id: 'a5ca00c0-b30c-11ea-9732-1bb05811278c',
description: '',
enabled: true,
@ -279,11 +282,9 @@ describe('When calling package policy', () => {
it('should not call packagePolicyPostCreate call back in case of packagePolicy create failed', async () => {
const request = getCreateKibanaRequest();
packagePolicyServiceMock.create.mockImplementationOnce(
async (soClient, esClient, newData) => {
throw new Error('foo');
}
);
packagePolicyServiceWithAuthzMock.create.mockImplementationOnce(() => {
throw new Error('foo');
});
await routeHandler(context, request, response);
const firstCB = packagePolicyServiceMock.runExternalCallbacks.mock.calls[0][0];

View file

@ -220,11 +220,16 @@ export const createPackagePolicyHandler: FleetRequestHandler<
);
// Create package policy
const packagePolicy = await packagePolicyService.create(soClient, esClient, newData, {
user,
force,
spaceId,
});
const packagePolicy = await fleetContext.packagePolicyService.asCurrentUser.create(
soClient,
esClient,
newData,
{
user,
force,
spaceId,
}
);
const enrichedPackagePolicy = await packagePolicyService.runExternalCallbacks(
'packagePolicyPostCreate',

View file

@ -84,9 +84,6 @@ export const registerRoutes = (router: FleetAuthzRouter) => {
{
path: PACKAGE_POLICY_API_ROUTES.CREATE_PATTERN,
validate: CreatePackagePolicyRequestSchema,
fleetAuthz: {
integrations: { writeIntegrationPolicies: true },
},
},
createPackagePolicyHandler
);

View file

@ -66,9 +66,9 @@ export async function getAuthzFromRequest(req: KibanaRequest): Promise<FleetAuth
const { privileges } = await checkPrivileges({
kibana: [
security.authz.actions.api.get(`${PLUGIN_ID}-all`),
security.authz.actions.api.get(`${PLUGIN_ID}-setup`),
security.authz.actions.api.get(`${INTEGRATIONS_PLUGIN_ID}-all`),
security.authz.actions.api.get(`${INTEGRATIONS_PLUGIN_ID}-read`),
security.authz.actions.api.get('fleet-setup'),
],
});
const fleetAllAuth = getAuthorizationFromPrivileges(privileges.kibana, `${PLUGIN_ID}-all`);
@ -84,14 +84,20 @@ export async function getAuthzFromRequest(req: KibanaRequest): Promise<FleetAuth
return calculateAuthz({
fleet: { all: fleetAllAuth, setup: fleetSetupAuth },
integrations: { all: intAllAuth, read: intReadAuth },
integrations: {
all: intAllAuth,
read: intReadAuth,
},
isSuperuser: checkSuperuser(req),
});
}
return calculateAuthz({
fleet: { all: false, setup: false },
integrations: { all: false, read: false },
integrations: {
all: false,
read: false,
},
isSuperuser: false,
});
}
@ -118,7 +124,7 @@ function containsRequirement(authz: Authz, requirements: DeepPartialTruthy<Authz
return true;
}
function hasRequiredFleetAuthzPrivilege(
export function hasRequiredFleetAuthzPrivilege(
authz: FleetAuthz,
{ fleetAuthz }: { fleetAuthz?: FleetAuthzRequirements }
): boolean {
@ -146,7 +152,7 @@ type FleetAuthzRouteRegistrar<
handler: RequestHandler<P, Q, B, Context, Method>
) => void;
interface FleetAuthzRouteConfig {
export interface FleetAuthzRouteConfig {
fleetAuthz?: FleetAuthzRequirements;
}

View file

@ -10,7 +10,11 @@ import { httpServerMock, savedObjectsClientMock, coreMock } from '@kbn/core/serv
import type { PostFleetSetupResponse } from '../../../common/types';
import { RegistryError } from '../../errors';
import { createAppContextStartContractMock, xpackMocks } from '../../mocks';
import {
createAppContextStartContractMock,
createPackagePolicyServiceMock,
xpackMocks,
} from '../../mocks';
import { agentServiceMock } from '../../services/agents/agent_service.mock';
import { appContextService } from '../../services/app_context';
import { setupFleet } from '../../services/setup';
@ -43,6 +47,10 @@ describe('FleetSetupHandler', () => {
asInternalUser: agentServiceMock.createClient(),
},
authz: createFleetAuthzMock(),
packagePolicyService: {
asCurrentUser: createPackagePolicyServiceMock(),
asInternalUser: createPackagePolicyServiceMock(),
},
epm: {
internalSoClient: savedObjectsClientMock.create(),
},

View file

@ -8,7 +8,7 @@
import type { SavedObjectsClientContract } from '@kbn/core/server';
import { savedObjectsClientMock } from '@kbn/core/server/mocks';
import type { PackagePolicyServiceInterface } from '../../package_policy';
import type { PackagePolicyClient } from '../../package_policy_service';
import * as storage from '../archive/storage';
import { packagePolicyService } from '../../package_policy';
@ -26,8 +26,7 @@ jest.mock('../../package_policy');
describe(' Cleanup old assets', () => {
let soClient: jest.Mocked<SavedObjectsClientContract>;
const packagePolicyServiceMock =
packagePolicyService as jest.Mocked<PackagePolicyServiceInterface>;
const packagePolicyServiceMock = packagePolicyService as jest.Mocked<PackagePolicyClient>;
let removeArchiveEntriesMock: jest.MockedFunction<typeof storage.removeArchiveEntries>;
function mockFindVersions(versions: string[]) {

View file

@ -4,6 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
/* eslint-disable max-classes-per-file */
import { omit, partition, isEqual } from 'lodash';
import { i18n } from '@kbn/i18n';
@ -64,6 +65,7 @@ import {
PackagePolicyRestrictionRelatedError,
PackagePolicyNotFoundError,
HostedAgentPolicyRestrictionRelatedError,
FleetUnauthorizedError,
} from '../errors';
import { NewPackagePolicySchema, PackagePolicySchema, UpdatePackagePolicySchema } from '../types';
import type {
@ -77,6 +79,9 @@ import type {
} from '../types';
import type { ExternalCallback } from '..';
import type { FleetAuthzRouteConfig } from '../routes/security';
import { getAuthzFromRequest, hasRequiredFleetAuthzPrivilege } from '../routes/security';
import { storedPackagePolicyToAgentInputs } from './agent_policies';
import { agentPolicyService } from './agent_policy';
import { getDataOutputForAgentPolicy } from './agent_policies';
@ -90,6 +95,7 @@ import type { PackageUpdateEvent, UpdateEventType } from './upgrade_sender';
import { sendTelemetryEvents } from './upgrade_sender';
import { handleExperimentalDatastreamFeatureOptIn } from './package_policies';
import { updateDatastreamExperimentalFeatures } from './epm/packages/update';
import type { PackagePolicyClient, PackagePolicyService } from './package_policy_service';
export type InputsOverride = Partial<NewPackagePolicyInput> & {
vars?: Array<NewPackagePolicyInput['vars'] & { name: string }>;
@ -106,7 +112,7 @@ export const DATA_STREAM_ALLOWED_INDEX_PRIVILEGES = new Set([
'read_cross_cluster',
]);
class PackagePolicyService implements PackagePolicyServiceInterface {
class PackagePolicyClientImpl implements PackagePolicyClient {
public async create(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
@ -1123,6 +1129,66 @@ class PackagePolicyService implements PackagePolicyServiceInterface {
}
}
export class PackagePolicyServiceImpl
extends PackagePolicyClientImpl
implements PackagePolicyService
{
public asScoped(request: KibanaRequest): PackagePolicyClient {
const preflightCheck = async (fleetAuthzConfig: FleetAuthzRouteConfig) => {
const authz = await getAuthzFromRequest(request);
if (!hasRequiredFleetAuthzPrivilege(authz, fleetAuthzConfig)) {
throw new FleetUnauthorizedError('Not authorized to this action on integration policies');
}
};
return new PackagePolicyClientWithAuthz(preflightCheck);
}
public get asInternalUser() {
return new PackagePolicyClientWithAuthz();
}
}
class PackagePolicyClientWithAuthz extends PackagePolicyClientImpl {
constructor(
private readonly preflightCheck?: (
fleetAuthzConfig: FleetAuthzRouteConfig
) => void | Promise<void>
) {
super();
}
#runPreflight = async (fleetAuthzConfig: FleetAuthzRouteConfig) => {
if (this.preflightCheck) {
return await this.preflightCheck(fleetAuthzConfig);
}
};
async create(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
packagePolicy: NewPackagePolicy,
options?: {
spaceId?: string;
id?: string;
user?: AuthenticatedUser;
bumpRevision?: boolean;
force?: boolean;
skipEnsureInstalled?: boolean;
skipUniqueNameVerification?: boolean;
overwrite?: boolean;
packageInfo?: PackageInfo;
}
): Promise<PackagePolicy> {
await this.#runPreflight({
fleetAuthz: {
integrations: { writeIntegrationPolicies: true },
},
});
return super.create(soClient, esClient, packagePolicy, options);
}
}
function validatePackagePolicyOrThrow(packagePolicy: NewPackagePolicy, pkgInfo: PackageInfo) {
const validationResults = validatePackagePolicy(packagePolicy, pkgInfo, safeLoad);
if (validationHasErrors(validationResults)) {
@ -1389,133 +1455,7 @@ export interface NewPackagePolicyWithId extends NewPackagePolicy {
policy_id: string;
}
export interface PackagePolicyServiceInterface {
create(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
packagePolicy: NewPackagePolicy,
options?: {
spaceId?: string;
id?: string;
user?: AuthenticatedUser;
bumpRevision?: boolean;
force?: boolean;
skipEnsureInstalled?: boolean;
skipUniqueNameVerification?: boolean;
overwrite?: boolean;
packageInfo?: PackageInfo;
}
): Promise<PackagePolicy>;
bulkCreate(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
packagePolicies: NewPackagePolicyWithId[],
options?: {
user?: AuthenticatedUser;
bumpRevision?: boolean;
force?: true;
}
): Promise<PackagePolicy[]>;
get(soClient: SavedObjectsClientContract, id: string): Promise<PackagePolicy | null>;
findAllForAgentPolicy(
soClient: SavedObjectsClientContract,
agentPolicyId: string
): Promise<PackagePolicy[]>;
getByIDs(
soClient: SavedObjectsClientContract,
ids: string[],
options?: { ignoreMissing?: boolean }
): Promise<PackagePolicy[] | null>;
list(
soClient: SavedObjectsClientContract,
options: ListWithKuery
): Promise<ListResult<PackagePolicy>>;
listIds(
soClient: SavedObjectsClientContract,
options: ListWithKuery
): Promise<ListResult<string>>;
update(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
id: string,
packagePolicyUpdate: UpdatePackagePolicy,
options?: { user?: AuthenticatedUser; force?: boolean },
currentVersion?: string
): Promise<PackagePolicy>;
delete(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
ids: string[],
options?: { user?: AuthenticatedUser; skipUnassignFromAgentPolicies?: boolean; force?: boolean }
): Promise<DeletePackagePoliciesResponse>;
upgrade(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
ids: string[],
options?: { user?: AuthenticatedUser },
packagePolicy?: PackagePolicy,
pkgVersion?: string
): Promise<UpgradePackagePolicyResponse>;
getUpgradeDryRunDiff(
soClient: SavedObjectsClientContract,
id: string,
packagePolicy?: PackagePolicy,
pkgVersion?: string
): Promise<UpgradePackagePolicyDryRunResponseItem>;
enrichPolicyWithDefaultsFromPackage(
soClient: SavedObjectsClientContract,
newPolicy: NewPackagePolicy
): Promise<NewPackagePolicy>;
buildPackagePolicyFromPackage(
soClient: SavedObjectsClientContract,
pkgName: string,
logger?: Logger
): Promise<NewPackagePolicy | undefined>;
runExternalCallbacks<A extends ExternalCallback[0]>(
externalCallbackType: A,
packagePolicy: A extends 'postPackagePolicyDelete'
? DeletePackagePoliciesResponse
: A extends 'packagePolicyPostCreate'
? PackagePolicy
: NewPackagePolicy,
context: RequestHandlerContext,
request: KibanaRequest
): Promise<
A extends 'postPackagePolicyDelete'
? void
: A extends 'packagePolicyPostCreate'
? PackagePolicy
: NewPackagePolicy
>;
runDeleteExternalCallbacks(deletedPackagePolicies: DeletePackagePoliciesResponse): Promise<void>;
getUpgradePackagePolicyInfo(
soClient: SavedObjectsClientContract,
id: string
): Promise<{
packagePolicy: PackagePolicy;
packageInfo: PackageInfo;
experimentalDataStreamFeatures: ExperimentalDataStreamFeature[];
}>;
}
export const packagePolicyService: PackagePolicyServiceInterface = new PackagePolicyService();
export type { PackagePolicyService };
export const packagePolicyService: PackagePolicyClient = new PackagePolicyClientImpl();
export function updatePackageInputs(
basePackagePolicy: NewPackagePolicy,

View file

@ -0,0 +1,156 @@
/*
* 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, Logger } from '@kbn/core/server';
import type {
ElasticsearchClient,
RequestHandlerContext,
SavedObjectsClientContract,
} from '@kbn/core/server';
import type { AuthenticatedUser } from '@kbn/security-plugin/server';
import type {
DeletePackagePoliciesResponse,
UpgradePackagePolicyResponse,
PackageInfo,
ListWithKuery,
ListResult,
UpgradePackagePolicyDryRunResponseItem,
} from '../../common';
import type { ExperimentalDataStreamFeature } from '../../common/types';
import type { NewPackagePolicy, UpdatePackagePolicy, PackagePolicy } from '../types';
import type { ExternalCallback } from '..';
import type { NewPackagePolicyWithId } from './package_policy';
export interface PackagePolicyService {
asScoped(request: KibanaRequest): PackagePolicyClient;
get asInternalUser(): PackagePolicyClient;
}
export interface PackagePolicyClient {
create(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
packagePolicy: NewPackagePolicy,
options?: {
spaceId?: string;
id?: string;
user?: AuthenticatedUser;
bumpRevision?: boolean;
force?: boolean;
skipEnsureInstalled?: boolean;
skipUniqueNameVerification?: boolean;
overwrite?: boolean;
packageInfo?: PackageInfo;
}
): Promise<PackagePolicy>;
bulkCreate(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
packagePolicies: NewPackagePolicyWithId[],
options?: {
user?: AuthenticatedUser;
bumpRevision?: boolean;
force?: true;
}
): Promise<PackagePolicy[]>;
get(soClient: SavedObjectsClientContract, id: string): Promise<PackagePolicy | null>;
findAllForAgentPolicy(
soClient: SavedObjectsClientContract,
agentPolicyId: string
): Promise<PackagePolicy[]>;
getByIDs(
soClient: SavedObjectsClientContract,
ids: string[],
options?: { ignoreMissing?: boolean }
): Promise<PackagePolicy[] | null>;
list(
soClient: SavedObjectsClientContract,
options: ListWithKuery
): Promise<ListResult<PackagePolicy>>;
listIds(
soClient: SavedObjectsClientContract,
options: ListWithKuery
): Promise<ListResult<string>>;
update(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
id: string,
packagePolicyUpdate: UpdatePackagePolicy,
options?: { user?: AuthenticatedUser; force?: boolean },
currentVersion?: string
): Promise<PackagePolicy>;
delete(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
ids: string[],
options?: { user?: AuthenticatedUser; skipUnassignFromAgentPolicies?: boolean; force?: boolean }
): Promise<DeletePackagePoliciesResponse>;
upgrade(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
ids: string[],
options?: { user?: AuthenticatedUser },
packagePolicy?: PackagePolicy,
pkgVersion?: string
): Promise<UpgradePackagePolicyResponse>;
getUpgradeDryRunDiff(
soClient: SavedObjectsClientContract,
id: string,
packagePolicy?: PackagePolicy,
pkgVersion?: string
): Promise<UpgradePackagePolicyDryRunResponseItem>;
enrichPolicyWithDefaultsFromPackage(
soClient: SavedObjectsClientContract,
newPolicy: NewPackagePolicy
): Promise<NewPackagePolicy>;
buildPackagePolicyFromPackage(
soClient: SavedObjectsClientContract,
pkgName: string,
logger?: Logger
): Promise<NewPackagePolicy | undefined>;
runExternalCallbacks<A extends ExternalCallback[0]>(
externalCallbackType: A,
packagePolicy: A extends 'postPackagePolicyDelete'
? DeletePackagePoliciesResponse
: A extends 'packagePolicyPostCreate'
? PackagePolicy
: NewPackagePolicy,
context: RequestHandlerContext,
request: KibanaRequest
): Promise<
A extends 'postPackagePolicyDelete'
? void
: A extends 'packagePolicyPostCreate'
? PackagePolicy
: NewPackagePolicy
>;
runDeleteExternalCallbacks(deletedPackagePolicies: DeletePackagePoliciesResponse): Promise<void>;
getUpgradePackagePolicyInfo(
soClient: SavedObjectsClientContract,
id: string
): Promise<{
packagePolicy: PackagePolicy;
packageInfo: PackageInfo;
experimentalDataStreamFeatures: ExperimentalDataStreamFeature[];
}>;
}

View file

@ -16,6 +16,7 @@ import type {
import type { FleetAuthz } from '../../common/authz';
import type { AgentClient } from '../services';
import type { PackagePolicyClient } from '../services/package_policy_service';
/** @internal */
export type FleetRequestHandlerContext = CustomRequestHandlerContext<{
@ -27,6 +28,10 @@ export type FleetRequestHandlerContext = CustomRequestHandlerContext<{
asCurrentUser: AgentClient;
asInternalUser: AgentClient;
};
packagePolicyService: {
asCurrentUser: PackagePolicyClient;
asInternalUser: PackagePolicyClient;
};
epm: {
/**
* Saved Objects client configured to use kibana_system privileges instead of end-user privileges. Should only be

View file

@ -12,7 +12,7 @@ import type {
FleetStartContract,
PackageService,
AgentPolicyServiceInterface,
PackagePolicyServiceInterface,
PackagePolicyClient,
} from '@kbn/fleet-plugin/server';
import type { ConfigType } from '../config';
import type { TelemetryEventsSender } from './telemetry/sender';
@ -35,7 +35,7 @@ export type OsqueryAppContextServiceStartContract = Partial<
export class OsqueryAppContextService {
private agentService: AgentService | undefined;
private packageService: PackageService | undefined;
private packagePolicyService: PackagePolicyServiceInterface | undefined;
private packagePolicyService: PackagePolicyClient | undefined;
private agentPolicyService: AgentPolicyServiceInterface | undefined;
public start(dependencies: OsqueryAppContextServiceStartContract) {
@ -56,7 +56,7 @@ export class OsqueryAppContextService {
return this.packageService;
}
public getPackagePolicyService(): PackagePolicyServiceInterface | undefined {
public getPackagePolicyService(): PackagePolicyClient | undefined {
return this.packagePolicyService;
}

View file

@ -16,7 +16,7 @@ import type {
AgentClient,
AgentPolicyServiceInterface,
PackageService,
PackagePolicyServiceInterface,
PackagePolicyClient,
} from '@kbn/fleet-plugin/server';
import { PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '@kbn/fleet-plugin/common';
import { OSQUERY_INTEGRATION_NAME } from '../../../common';
@ -34,7 +34,7 @@ export class TelemetryReceiver {
private agentClient?: AgentClient;
private agentPolicyService?: AgentPolicyServiceInterface;
private packageService?: PackageService;
private packagePolicyService?: PackagePolicyServiceInterface;
private packagePolicyService?: PackagePolicyClient;
private esClient?: ElasticsearchClient;
private soClient?: SavedObjectsClientContract;
private readonly max_records = 100;

View file

@ -11,7 +11,7 @@ import type {
AggregationsRateAggregate,
SearchResponse,
} from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import type { PackagePolicyServiceInterface } from '@kbn/fleet-plugin/server';
import type { PackagePolicyClient } from '@kbn/fleet-plugin/server';
import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server';
import type { ListResult, PackagePolicy } from '@kbn/fleet-plugin/common';
import {
@ -32,7 +32,7 @@ interface PolicyLevelUsage {
export async function getPolicyLevelUsage(
esClient: ElasticsearchClient,
soClient: SavedObjectsClientContract,
packagePolicyService?: PackagePolicyServiceInterface
packagePolicyService?: PackagePolicyClient
): Promise<PolicyLevelUsage> {
if (!packagePolicyService) {
return {};

View file

@ -16,7 +16,7 @@ import { createPackagePolicyServiceMock } from '@kbn/fleet-plugin/server/mocks';
import { PolicyWatcher } from './license_watch';
import type { ILicense } from '@kbn/licensing-plugin/common/types';
import { licenseMock } from '@kbn/licensing-plugin/common/licensing.mock';
import type { PackagePolicyServiceInterface } from '@kbn/fleet-plugin/server';
import type { PackagePolicyClient } from '@kbn/fleet-plugin/server';
import type { PackagePolicy } from '@kbn/fleet-plugin/common';
import { createPackagePolicyMock } from '@kbn/fleet-plugin/common/mocks';
import { policyFactory } from '../../../../common/endpoint/models/policy_config';
@ -37,7 +37,7 @@ describe('Policy-Changing license watcher', () => {
const logger = loggingSystemMock.create().get('license_watch.test');
const soStartMock = savedObjectsServiceMock.createStartContract();
const esStartMock = elasticsearchServiceMock.createStart();
let packagePolicySvcMock: jest.Mocked<PackagePolicyServiceInterface>;
let packagePolicySvcMock: jest.Mocked<PackagePolicyClient>;
const Platinum = licenseMock.createLicense({ license: { type: 'platinum', mode: 'platinum' } });
const Gold = licenseMock.createLicense({ license: { type: 'gold', mode: 'gold' } });

View file

@ -17,7 +17,7 @@ import type {
} from '@kbn/core/server';
import type { PackagePolicy } from '@kbn/fleet-plugin/common';
import { PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '@kbn/fleet-plugin/common';
import type { PackagePolicyServiceInterface } from '@kbn/fleet-plugin/server';
import type { PackagePolicyClient } from '@kbn/fleet-plugin/server';
import type { ILicense } from '@kbn/licensing-plugin/common/types';
import {
isEndpointPolicyValidForLicense,
@ -30,11 +30,11 @@ import { getPolicyDataForUpdate } from '../../../../common/endpoint/service/poli
export class PolicyWatcher {
private logger: Logger;
private esClient: ElasticsearchClient;
private policyService: PackagePolicyServiceInterface;
private policyService: PackagePolicyClient;
private subscription: Subscription | undefined;
private soStart: SavedObjectsServiceStart;
constructor(
policyService: PackagePolicyServiceInterface,
policyService: PackagePolicyClient,
soStart: SavedObjectsServiceStart,
esStart: ElasticsearchServiceStart,
logger: Logger

View file

@ -41,7 +41,7 @@ import type {
AgentClient,
PackageService,
PackageClient,
PackagePolicyServiceInterface,
PackagePolicyClient,
} from '@kbn/fleet-plugin/server';
import {
HOST_METADATA_GET_ROUTE,
@ -112,7 +112,7 @@ describe('test endpoint routes', () => {
startContract = createMockEndpointAppContextServiceStartContract();
(
startContract.packagePolicyService as jest.Mocked<PackagePolicyServiceInterface>
startContract.packagePolicyService as jest.Mocked<PackagePolicyClient>
).list.mockImplementation(() => {
return Promise.resolve({
items: [],

View file

@ -9,13 +9,13 @@ import type { SavedObjectsClientContract } from '@kbn/core/server';
import { savedObjectsClientMock } from '@kbn/core/server/mocks';
import { createPackagePolicyServiceMock } from '@kbn/fleet-plugin/server/mocks';
import type { PackagePolicy } from '@kbn/fleet-plugin/common/types/models';
import type { PackagePolicyServiceInterface } from '@kbn/fleet-plugin/server';
import type { PackagePolicyClient } from '@kbn/fleet-plugin/server';
import { getAllEndpointPackagePolicies } from './endpoint_package_policies';
describe('endpoint_package_policies', () => {
describe('getAllEndpointPackagePolicies', () => {
let mockSavedObjectClient: jest.Mocked<SavedObjectsClientContract>;
let mockPackagePolicyService: jest.Mocked<PackagePolicyServiceInterface>;
let mockPackagePolicyService: jest.Mocked<PackagePolicyClient>;
beforeEach(() => {
mockSavedObjectClient = savedObjectsClientMock.create();

View file

@ -6,11 +6,11 @@
*/
import type { SavedObjectsClientContract } from '@kbn/core/server';
import type { PackagePolicyServiceInterface } from '@kbn/fleet-plugin/server';
import type { PackagePolicyClient } from '@kbn/fleet-plugin/server';
import type { PackagePolicy } from '@kbn/fleet-plugin/common/types/models';
export const getAllEndpointPackagePolicies = async (
packagePolicyService: PackagePolicyServiceInterface,
packagePolicyService: PackagePolicyClient,
soClient: SavedObjectsClientContract
): Promise<PackagePolicy[]> => {
const result: PackagePolicy[] = [];

View file

@ -12,11 +12,11 @@ import {
createPackagePolicyServiceMock,
} from '@kbn/fleet-plugin/server/mocks';
import type { Agent, PackagePolicy } from '@kbn/fleet-plugin/common/types/models';
import type { PackagePolicyServiceInterface } from '@kbn/fleet-plugin/server';
import type { PackagePolicyClient } from '@kbn/fleet-plugin/server';
describe('test find all unenrolled Agent id', () => {
let mockAgentClient: jest.Mocked<AgentClient>;
let mockPackagePolicyService: jest.Mocked<PackagePolicyServiceInterface>;
let mockPackagePolicyService: jest.Mocked<PackagePolicyClient>;
beforeEach(() => {
mockAgentClient = createMockAgentClient();

View file

@ -8,7 +8,7 @@
import LRU from 'lru-cache';
import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks';
import type { Logger } from '@kbn/core/server';
import type { PackagePolicyServiceInterface } from '@kbn/fleet-plugin/server';
import type { PackagePolicyClient } from '@kbn/fleet-plugin/server';
import { createPackagePolicyServiceMock } from '@kbn/fleet-plugin/server/mocks';
import type { ExceptionListClient } from '@kbn/lists-plugin/server';
import { listMock } from '@kbn/lists-plugin/server/mocks';
@ -64,7 +64,7 @@ export enum ManifestManagerMockType {
export interface ManifestManagerMockOptions {
cache: LRU<string, Buffer>;
exceptionListClient: ExceptionListClient;
packagePolicyService: jest.Mocked<PackagePolicyServiceInterface>;
packagePolicyService: jest.Mocked<PackagePolicyClient>;
savedObjectsClient: ReturnType<typeof savedObjectsClientMock.create>;
}

View file

@ -21,7 +21,7 @@ import {
ENDPOINT_HOST_ISOLATION_EXCEPTIONS_LIST_ID,
} from '@kbn/securitysolution-list-constants';
import type { ListResult } from '@kbn/fleet-plugin/common';
import type { PackagePolicyServiceInterface } from '@kbn/fleet-plugin/server';
import type { PackagePolicyClient } from '@kbn/fleet-plugin/server';
import type { ExceptionListClient } from '@kbn/lists-plugin/server';
import type { ManifestSchemaVersion } from '../../../../../common/endpoint/schema/common';
import type { ManifestSchema } from '../../../../../common/endpoint/schema/manifest';
@ -92,7 +92,7 @@ export interface ManifestManagerContext {
savedObjectsClient: SavedObjectsClientContract;
artifactClient: EndpointArtifactClientInterface;
exceptionListClient: ExceptionListClient;
packagePolicyService: PackagePolicyServiceInterface;
packagePolicyService: PackagePolicyClient;
logger: Logger;
cache: LRU<string, Buffer>;
experimentalFeatures: ExperimentalFeatures;
@ -109,7 +109,7 @@ const manifestsEqual = (manifest1: ManifestSchema, manifest2: ManifestSchema) =>
export class ManifestManager {
protected artifactClient: EndpointArtifactClientInterface;
protected exceptionListClient: ExceptionListClient;
protected packagePolicyService: PackagePolicyServiceInterface;
protected packagePolicyService: PackagePolicyClient;
protected savedObjectsClient: SavedObjectsClientContract;
protected logger: Logger;
protected cache: LRU<string, Buffer>;

View file

@ -14,7 +14,7 @@ import type {
AgentClient,
AgentPolicyServiceInterface,
FleetStartContract,
PackagePolicyServiceInterface,
PackagePolicyClient,
PackageClient,
} from '@kbn/fleet-plugin/server';
import { createInternalReadonlySoClient } from '../../utils/create_internal_readonly_so_client';
@ -79,7 +79,7 @@ export interface EndpointFleetServicesInterface {
agent: AgentClient;
agentPolicy: AgentPolicyServiceInterface;
packages: PackageClient;
packagePolicy: PackagePolicyServiceInterface;
packagePolicy: PackagePolicyClient;
}
export interface EndpointScopedFleetServicesInterface extends EndpointFleetServicesInterface {

View file

@ -14,10 +14,7 @@ import type {
import type { SearchTotalHits, SearchResponse } from '@elastic/elasticsearch/lib/api/types';
import type { Agent, AgentPolicy, PackagePolicy } from '@kbn/fleet-plugin/common';
import type {
AgentPolicyServiceInterface,
PackagePolicyServiceInterface,
} from '@kbn/fleet-plugin/server';
import type { AgentPolicyServiceInterface, PackagePolicyClient } from '@kbn/fleet-plugin/server';
import { AgentNotFoundError } from '@kbn/fleet-plugin/server';
import { getAgentStatus } from '@kbn/fleet-plugin/common/services/agent_status';
import type {
@ -77,7 +74,7 @@ export class EndpointMetadataService {
constructor(
private savedObjectsStart: SavedObjectsServiceStart,
private readonly agentPolicyService: AgentPolicyServiceInterface,
private readonly packagePolicyService: PackagePolicyServiceInterface,
private readonly packagePolicyService: PackagePolicyClient,
private readonly logger?: Logger
) {}

View file

@ -15,7 +15,7 @@ import { EndpointArtifactExceptionValidationError } from './errors';
import { httpServerMock } from '@kbn/core/server/mocks';
import type { PackagePolicy } from '@kbn/fleet-plugin/common';
import { createFleetAuthzMock } from '@kbn/fleet-plugin/common';
import type { PackagePolicyServiceInterface } from '@kbn/fleet-plugin/server';
import type { PackagePolicyClient } from '@kbn/fleet-plugin/server';
import type { ExceptionItemLikeOptions } from '../types';
import {
BY_POLICY_ARTIFACT_TAG_PREFIX,
@ -28,7 +28,7 @@ describe('When using Artifacts Exceptions BaseValidator', () => {
let kibanaRequest: ReturnType<typeof httpServerMock.createKibanaRequest>;
let exceptionLikeItem: ExceptionItemLikeOptions;
let validator: BaseValidatorMock;
let packagePolicyService: jest.Mocked<PackagePolicyServiceInterface>;
let packagePolicyService: jest.Mocked<PackagePolicyClient>;
let initValidator: (withNoAuth?: boolean, withBasicLicense?: boolean) => BaseValidatorMock;
beforeEach(() => {
@ -37,8 +37,7 @@ describe('When using Artifacts Exceptions BaseValidator', () => {
const servicesStart = createMockEndpointAppContextServiceStartContract();
packagePolicyService =
servicesStart.packagePolicyService as jest.Mocked<PackagePolicyServiceInterface>;
packagePolicyService = servicesStart.packagePolicyService as jest.Mocked<PackagePolicyClient>;
endpointAppContextServices = new EndpointAppContextService();
endpointAppContextServices.setup(createMockEndpointAppContextServiceSetupContract());

View file

@ -54,12 +54,12 @@ export default function (providerContext: FtrProviderContext) {
});
});
it('should return a 400 with a user without the correct ES permissions', async () => {
it('should return a 403 with a user without the correct ES permissions', async () => {
await supertestWithoutAuth
.post(`/api/fleet/logstash_api_keys`)
.auth(testUsers.fleet_all_int_all.username, testUsers.fleet_all_int_all.password)
.set('kbn-xsrf', 'xxx')
.expect(400);
.expect(403);
});
});
}