diff --git a/src/lib/features/playground/advanced-playground.test.ts b/src/lib/features/playground/advanced-playground.test.ts index bf53d177f9..c2e6c8c52f 100644 --- a/src/lib/features/playground/advanced-playground.test.ts +++ b/src/lib/features/playground/advanced-playground.test.ts @@ -19,6 +19,7 @@ beforeAll(async () => { advancedPlayground: true, strictSchemaValidation: true, strategyVariant: true, + privateProjects: true, }, }, }, diff --git a/src/lib/features/playground/playground-service.ts b/src/lib/features/playground/playground-service.ts index ef4495c1c0..4ffcf8d813 100644 --- a/src/lib/features/playground/playground-service.ts +++ b/src/lib/features/playground/playground-service.ts @@ -4,7 +4,7 @@ import { IUnleashServices } from 'lib/types/services'; import { ALL } from '../../types/models/api-token'; import { PlaygroundFeatureSchema } from 'lib/openapi/spec/playground-feature-schema'; import { Logger } from '../../logger'; -import { ISegment, IUnleashConfig } from 'lib/types'; +import { IFlagResolver, ISegment, IUnleashConfig } from 'lib/types'; import { offlineUnleashClient } from './offline-unleash-client'; import { FeatureInterface } from 'lib/features/playground/feature-evaluator/feature'; import { @@ -16,10 +16,11 @@ import { FeatureConfigurationClient } from '../../types/stores/feature-strategie import { generateObjectCombinations } from './generateObjectCombinations'; import groupBy from 'lodash.groupby'; import { omitKeys } from '../../util'; -import { AdvancedPlaygroundFeatureSchema } from '../../openapi/spec/advanced-playground-feature-schema'; +import { AdvancedPlaygroundFeatureSchema } from '../../openapi'; import { AdvancedPlaygroundEnvironmentFeatureSchema } from '../../openapi/spec/advanced-playground-environment-feature-schema'; import { validateQueryComplexity } from './validateQueryComplexity'; import { playgroundStrategyEvaluation } from 'lib/openapi'; +import { IPrivateProjectChecker } from '../private-project/privateProjectCheckerType'; type EvaluationInput = { features: FeatureConfigurationClient[]; @@ -66,16 +67,28 @@ export class PlaygroundService { private readonly segmentService: ISegmentService; + private flagResolver: IFlagResolver; + + private privateProjectChecker: IPrivateProjectChecker; + constructor( config: IUnleashConfig, { featureToggleServiceV2, segmentService, - }: Pick, + privateProjectChecker, + }: Pick< + IUnleashServices, + | 'featureToggleServiceV2' + | 'segmentService' + | 'privateProjectChecker' + >, ) { this.logger = config.getLogger('services/playground-service.ts'); + this.flagResolver = config.flagResolver; this.featureToggleService = featureToggleServiceV2; this.segmentService = segmentService; + this.privateProjectChecker = privateProjectChecker; } async evaluateAdvancedQuery( @@ -83,10 +96,29 @@ export class PlaygroundService { environments: string[], context: SdkContextSchema, limit: number, + userId: number, ): Promise { const segments = await this.segmentService.getActive(); + + let filteredProjects: typeof projects; + if (this.flagResolver.isEnabled('privateProjects')) { + const accessibleProjects = + await this.privateProjectChecker.getUserAccessibleProjects( + userId, + ); + filteredProjects = + projects === ALL + ? accessibleProjects + : projects.filter((project) => + accessibleProjects.includes(project), + ); + console.log(accessibleProjects); + } + const environmentFeatures = await Promise.all( - environments.map((env) => this.resolveFeatures(projects, env)), + environments.map((env) => + this.resolveFeatures(filteredProjects, env), + ), ); const contexts = generateObjectCombinations(context); diff --git a/src/lib/features/playground/playground.ts b/src/lib/features/playground/playground.ts index ef165a9890..5822f4ea43 100644 --- a/src/lib/features/playground/playground.ts +++ b/src/lib/features/playground/playground.ts @@ -20,6 +20,7 @@ import { advancedPlaygroundViewModel, playgroundViewModel, } from './playground-view-model'; +import { IAuthRequest } from '../../routes/unleash-types'; export default class PlaygroundController extends Controller { private openApiService: OpenApiService; @@ -112,9 +113,10 @@ export default class PlaygroundController extends Controller { } async evaluateAdvancedContext( - req: Request, + req: IAuthRequest, res: Response, ): Promise { + const { user } = req; // used for runtime control, do not remove const { payload } = this.flagResolver.getVariant('advancedPlayground'); const limit = @@ -127,6 +129,7 @@ export default class PlaygroundController extends Controller { req.body.environments, req.body.context, limit, + user.id, ); const response: AdvancedPlaygroundResponseSchema = diff --git a/src/lib/services/client-metrics/instance-service.ts b/src/lib/services/client-metrics/instance-service.ts index 8cb503d5a7..19cca5a26b 100644 --- a/src/lib/services/client-metrics/instance-service.ts +++ b/src/lib/services/client-metrics/instance-service.ts @@ -20,6 +20,7 @@ import { clientMetricsSchema } from './schema'; import { PartialSome } from '../../types/partial'; import { IPrivateProjectChecker } from '../../features/private-project/privateProjectCheckerType'; import { IFlagResolver } from '../../types'; +import { ALL_PROJECTS } from '../../util'; export default class ClientInstanceService { apps = {}; @@ -178,7 +179,7 @@ export default class ClientInstanceService { ): Promise { const applications = await this.clientApplicationsStore.getAppsForStrategy(query); - if (this.flagResolver.isEnabled('privateProjects') && userId) { + if (this.flagResolver.isEnabled('privateProjects')) { const accessibleProjects = await this.privateProjectChecker.getUserAccessibleProjects( userId, @@ -188,7 +189,7 @@ export default class ClientInstanceService { ...application, usage: application.usage?.filter( (usageItem) => - usageItem.project === '*' || + usageItem.project === ALL_PROJECTS || accessibleProjects.includes(usageItem.project), ), }; diff --git a/src/lib/services/index.ts b/src/lib/services/index.ts index 433f008bb9..a3db29e6cf 100644 --- a/src/lib/services/index.ts +++ b/src/lib/services/index.ts @@ -251,6 +251,7 @@ export const createServices = ( const playgroundService = new PlaygroundService(config, { featureToggleServiceV2, segmentService, + privateProjectChecker, }); const configurationRevisionService = new ConfigurationRevisionService( diff --git a/src/test/e2e/services/playground-service.test.ts b/src/test/e2e/services/playground-service.test.ts index 058e713b6f..89b1dc0758 100644 --- a/src/test/e2e/services/playground-service.test.ts +++ b/src/test/e2e/services/playground-service.test.ts @@ -63,6 +63,7 @@ beforeAll(async () => { service = new PlaygroundService(config, { featureToggleServiceV2: featureToggleService, segmentService, + privateProjectChecker, }); });