mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-05 17:53:12 +02:00
feat: start extracting project from token
This commit is contained in:
parent
9aee1a7c42
commit
573a04531a
@ -10,6 +10,7 @@ import type { Logger, LogProvider } from '../logger';
|
|||||||
import type { Db } from './db';
|
import type { Db } from './db';
|
||||||
import type { IApplicationOverview } from '../features/metrics/instance/models';
|
import type { IApplicationOverview } from '../features/metrics/instance/models';
|
||||||
import { applySearchFilters } from '../features/feature-search/search-utils';
|
import { applySearchFilters } from '../features/feature-search/search-utils';
|
||||||
|
import type { IFlagResolver } from '../types';
|
||||||
|
|
||||||
const COLUMNS = [
|
const COLUMNS = [
|
||||||
'app_name',
|
'app_name',
|
||||||
@ -110,14 +111,6 @@ const remapRow = (input) => {
|
|||||||
return temp;
|
return temp;
|
||||||
};
|
};
|
||||||
|
|
||||||
const remapUsageRow = (input) => {
|
|
||||||
return {
|
|
||||||
app_name: input.appName,
|
|
||||||
project: input.project || '*',
|
|
||||||
environment: input.environment || '*',
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class ClientApplicationsStore
|
export default class ClientApplicationsStore
|
||||||
implements IClientApplicationsStore
|
implements IClientApplicationsStore
|
||||||
{
|
{
|
||||||
@ -125,24 +118,32 @@ export default class ClientApplicationsStore
|
|||||||
|
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
|
|
||||||
constructor(db: Db, eventBus: EventEmitter, getLogger: LogProvider) {
|
private flagResolver: IFlagResolver;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
db: Db,
|
||||||
|
eventBus: EventEmitter,
|
||||||
|
getLogger: LogProvider,
|
||||||
|
flagResolver: IFlagResolver,
|
||||||
|
) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
|
this.flagResolver = flagResolver;
|
||||||
this.logger = getLogger('client-applications-store.ts');
|
this.logger = getLogger('client-applications-store.ts');
|
||||||
}
|
}
|
||||||
|
|
||||||
async upsert(details: Partial<IClientApplication>): Promise<void> {
|
async upsert(details: Partial<IClientApplication>): Promise<void> {
|
||||||
const row = remapRow(details);
|
const row = remapRow(details);
|
||||||
await this.db(TABLE).insert(row).onConflict('app_name').merge();
|
await this.db(TABLE).insert(row).onConflict('app_name').merge();
|
||||||
const usageRow = remapUsageRow(details);
|
const usageRows = this.remapUsageRow(details);
|
||||||
await this.db(TABLE_USAGE)
|
await this.db(TABLE_USAGE)
|
||||||
.insert(usageRow)
|
.insert(usageRows)
|
||||||
.onConflict(['app_name', 'project', 'environment'])
|
.onConflict(['app_name', 'project', 'environment'])
|
||||||
.merge();
|
.merge();
|
||||||
}
|
}
|
||||||
|
|
||||||
async bulkUpsert(apps: Partial<IClientApplication>[]): Promise<void> {
|
async bulkUpsert(apps: Partial<IClientApplication>[]): Promise<void> {
|
||||||
const rows = apps.map(remapRow);
|
const rows = apps.map(remapRow);
|
||||||
const usageRows = apps.map(remapUsageRow);
|
const usageRows = apps.flatMap(this.remapUsageRow);
|
||||||
await this.db(TABLE).insert(rows).onConflict('app_name').merge();
|
await this.db(TABLE).insert(rows).onConflict('app_name').merge();
|
||||||
await this.db(TABLE_USAGE)
|
await this.db(TABLE_USAGE)
|
||||||
.insert(usageRows)
|
.insert(usageRows)
|
||||||
@ -420,4 +421,31 @@ export default class ClientApplicationsStore
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private remapUsageRow = (input) => {
|
||||||
|
console.log(input);
|
||||||
|
if (this.flagResolver.isEnabled('parseProjectFromSession')) {
|
||||||
|
if (!input.projects || input.projects.length === 0) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
app_name: input.appName,
|
||||||
|
project: '*',
|
||||||
|
environment: input.environment || '*',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
return input.projects.map((project) => ({
|
||||||
|
app_name: input.appName,
|
||||||
|
project: project,
|
||||||
|
environment: input.environment || '*',
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
app_name: input.appName,
|
||||||
|
project: input.project || '*',
|
||||||
|
environment: input.environment || '*',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,7 @@ export const createStores = (
|
|||||||
db,
|
db,
|
||||||
eventBus,
|
eventBus,
|
||||||
getLogger,
|
getLogger,
|
||||||
|
config.flagResolver,
|
||||||
),
|
),
|
||||||
clientInstanceStore: new ClientInstanceStore(db, eventBus, getLogger),
|
clientInstanceStore: new ClientInstanceStore(db, eventBus, getLogger),
|
||||||
clientMetricsStoreV2: new ClientMetricsStoreV2(
|
clientMetricsStoreV2: new ClientMetricsStoreV2(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { Response } from 'express';
|
import type { Response } from 'express';
|
||||||
import Controller from '../../../routes/controller';
|
import Controller from '../../../routes/controller';
|
||||||
import type { IUnleashServices } from '../../../types';
|
import type { IFlagResolver, IUnleashServices } from '../../../types';
|
||||||
import type { IUnleashConfig } from '../../../types/option';
|
import type { IUnleashConfig } from '../../../types/option';
|
||||||
import type { Logger } from '../../../logger';
|
import type { Logger } from '../../../logger';
|
||||||
import type ClientInstanceService from './instance-service';
|
import type ClientInstanceService from './instance-service';
|
||||||
@ -24,6 +24,8 @@ export default class RegisterController extends Controller {
|
|||||||
|
|
||||||
openApiService: OpenApiService;
|
openApiService: OpenApiService;
|
||||||
|
|
||||||
|
flagResolver: IFlagResolver;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
{
|
{
|
||||||
clientInstanceService,
|
clientInstanceService,
|
||||||
@ -35,6 +37,7 @@ export default class RegisterController extends Controller {
|
|||||||
this.logger = config.getLogger('/api/client/register');
|
this.logger = config.getLogger('/api/client/register');
|
||||||
this.clientInstanceService = clientInstanceService;
|
this.clientInstanceService = clientInstanceService;
|
||||||
this.openApiService = openApiService;
|
this.openApiService = openApiService;
|
||||||
|
this.flagResolver = config.flagResolver;
|
||||||
|
|
||||||
this.route({
|
this.route({
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@ -62,7 +65,7 @@ export default class RegisterController extends Controller {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static resolveEnvironment(
|
private resolveEnvironment(
|
||||||
user: IUser | IApiUser,
|
user: IUser | IApiUser,
|
||||||
data: Partial<IClientApp>,
|
data: Partial<IClientApp>,
|
||||||
) {
|
) {
|
||||||
@ -76,7 +79,14 @@ export default class RegisterController extends Controller {
|
|||||||
return 'default';
|
return 'default';
|
||||||
}
|
}
|
||||||
|
|
||||||
private static extractProjectFromRequest(
|
private resolveProject(user: IUser | IApiUser) {
|
||||||
|
if (user instanceof ApiUser) {
|
||||||
|
return user.projects;
|
||||||
|
}
|
||||||
|
return ['default'];
|
||||||
|
}
|
||||||
|
|
||||||
|
private extractProjectFromRequest(
|
||||||
req: IAuthRequest<unknown, void, ClientApplicationSchema>,
|
req: IAuthRequest<unknown, void, ClientApplicationSchema>,
|
||||||
) {
|
) {
|
||||||
const token = req.get('Authorisation') || req.headers.authorization;
|
const token = req.get('Authorisation') || req.headers.authorization;
|
||||||
@ -91,8 +101,15 @@ export default class RegisterController extends Controller {
|
|||||||
res: Response<void>,
|
res: Response<void>,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const { body: data, ip: clientIp, user } = req;
|
const { body: data, ip: clientIp, user } = req;
|
||||||
data.environment = RegisterController.resolveEnvironment(user, data);
|
data.environment = this.resolveEnvironment(user, data);
|
||||||
data.project = RegisterController.extractProjectFromRequest(req);
|
if (this.flagResolver.isEnabled('parseProjectFromSession')) {
|
||||||
|
data.projects = this.resolveProject(user);
|
||||||
|
console.log('Project from session: ', data.projects);
|
||||||
|
} else {
|
||||||
|
data.project = this.extractProjectFromRequest(req);
|
||||||
|
console.log('Project from request: ', data.project);
|
||||||
|
}
|
||||||
|
|
||||||
await this.clientInstanceService.registerClient(data, clientIp);
|
await this.clientInstanceService.registerClient(data, clientIp);
|
||||||
res.header('X-Unleash-Version', version).status(202).end();
|
res.header('X-Unleash-Version', version).status(202).end();
|
||||||
}
|
}
|
||||||
|
@ -92,4 +92,5 @@ export const clientRegisterSchema = joi
|
|||||||
interval: joi.number().required(),
|
interval: joi.number().required(),
|
||||||
environment: joi.string().optional(),
|
environment: joi.string().optional(),
|
||||||
project: joi.string().optional(),
|
project: joi.string().optional(),
|
||||||
|
projects: joi.array().optional().items(joi.string()),
|
||||||
});
|
});
|
||||||
|
@ -59,7 +59,8 @@ export type IFlagKey =
|
|||||||
| 'bearerTokenMiddleware'
|
| 'bearerTokenMiddleware'
|
||||||
| 'projectOverviewRefactorFeedback'
|
| 'projectOverviewRefactorFeedback'
|
||||||
| 'featureLifecycle'
|
| 'featureLifecycle'
|
||||||
| 'projectListFilterMyProjects';
|
| 'projectListFilterMyProjects'
|
||||||
|
| 'parseProjectFromSession';
|
||||||
|
|
||||||
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
||||||
|
|
||||||
@ -293,6 +294,10 @@ const flags: IFlags = {
|
|||||||
process.env.UNLEASH_EXPERIMENTAL_PROJECTS_LIST_MY_PROJECTS,
|
process.env.UNLEASH_EXPERIMENTAL_PROJECTS_LIST_MY_PROJECTS,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
parseProjectFromSession: parseEnvVarBoolean(
|
||||||
|
process.env.UNLEASH_EXPERIMENTAL_PARSE_PROJECT_FROM_SESSION,
|
||||||
|
false,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultExperimentalOptions: IExperimentalOptions = {
|
export const defaultExperimentalOptions: IExperimentalOptions = {
|
||||||
|
@ -56,6 +56,7 @@ process.nextTick(async () => {
|
|||||||
projectOverviewRefactorFeedback: true,
|
projectOverviewRefactorFeedback: true,
|
||||||
featureLifecycle: true,
|
featureLifecycle: true,
|
||||||
projectListFilterMyProjects: true,
|
projectListFilterMyProjects: true,
|
||||||
|
parseProjectFromSession: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
authentication: {
|
authentication: {
|
||||||
|
Loading…
Reference in New Issue
Block a user