Skip to content

Commit 105e4b3

Browse files
committed
add history plugin for runtime service and reuse computeDeltaWithOriginals for sync change logging
1 parent 1962f38 commit 105e4b3

File tree

7 files changed

+144
-267
lines changed

7 files changed

+144
-267
lines changed

src/casl/casl-ability.factory.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { UserIdentity } from "src/users/schemas/user-identity.schema";
2929
import { UserSettings } from "src/users/schemas/user-settings.schema";
3030
import { User } from "src/users/schemas/user.schema";
3131
import { Action } from "./action.enum";
32+
import { RuntimeConfig } from "src/runtime-config/schemas/runtime-config.schema";
3233

3334
type Subjects =
3435
| string
@@ -49,6 +50,7 @@ type Subjects =
4950
| typeof UserSettings
5051
| typeof ElasticSearchActions
5152
| typeof Datablock
53+
| typeof RuntimeConfig
5254
>
5355
| "all";
5456
type PossibleAbilities = [Action, Subjects];
@@ -84,6 +86,7 @@ export class CaslAbilityFactory {
8486
attachments: this.attachmentEndpointAccess,
8587
history: this.historyEndpointAccess,
8688
datablocks: this.datablockEndpointAccess,
89+
runtimeconfig: this.runtimeConfigEndpointAccess,
8790
};
8891

8992
endpointAccess(endpoint: string, user: JWTUser) {
@@ -908,6 +911,26 @@ export class CaslAbilityFactory {
908911
item.constructor as ExtractSubjectType<Subjects>,
909912
});
910913
}
914+
runtimeConfigEndpointAccess(user: JWTUser) {
915+
const { can, build } = new AbilityBuilder(
916+
createMongoAbility<PossibleAbilities, Conditions>,
917+
);
918+
919+
can(Action.Read, RuntimeConfig);
920+
if (
921+
user &&
922+
user.currentGroups.some((g) => this.accessGroups?.admin.includes(g))
923+
) {
924+
/*
925+
/ user that belongs to any of the group listed in ADMIN_GROUPS
926+
*/
927+
can(Action.Update, RuntimeConfig);
928+
}
929+
return build({
930+
detectSubjectType: (item) =>
931+
item.constructor as ExtractSubjectType<Subjects>,
932+
});
933+
}
911934

912935
policyEndpointAccess(user: JWTUser) {
913936
const { can, build } = new AbilityBuilder(

src/config/configuration.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,12 @@ const configuration = () => {
193193
);
194194

195195
const config = {
196+
configSyncToDb: {
197+
enabled: boolean(process.env.CONFIG_SYNC_TO_DB_ENABLED || false),
198+
configList: process.env.CONFIG_SYNC_TO_DB_LIST
199+
? process.env.CONFIG_SYNC_TO_DB_LIST.split(",").map((v) => v.trim())
200+
: ["frontendConfig", "frontendTheme"],
201+
},
196202
maxFileUploadSizeInMb: process.env.MAX_FILE_UPLOAD_SIZE || "16mb", // 16MB by default
197203
versions: {
198204
api: "3",

src/config/frontend.config.json

Lines changed: 4 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,4 @@
11
{
2-
"defaultMainPage": {
3-
"nonAuthenticatedUser": "DATASETS",
4-
"authenticatedUser": "PROPOSALS"
5-
},
6-
"checkBoxFilterClickTrigger": false,
7-
"accessTokenPrefix": "Bearer ",
8-
"addDatasetEnabled": true,
9-
"archiveWorkflowEnabled": false,
10-
"datasetReduceEnabled": true,
11-
"datasetJsonScientificMetadata": true,
12-
"editDatasetEnabled": true,
13-
"editDatasetSampleEnabled": true,
142
"editMetadataEnabled": true,
153
"addSampleEnabled": false,
164
"externalAuthEndpoint": "/api/v3/auth/msad",
@@ -244,7 +232,8 @@
244232
"description": "Filter by creation time of the dataset",
245233
"enabled": true
246234
}
247-
]
235+
],
236+
"conditions": []
248237
},
249238
"defaultProposalsListSettings": {
250239
"columns": [
@@ -344,13 +333,9 @@
344333
},
345334
"dateFormat": "yyyy-MM-dd HH:mm",
346335
"datasetDetailComponent": {
347-
"enableCustomizedComponent": false,
336+
"enableCustomizedComponent": true,
348337
"customization": [
349338
{
350-
"type": "regular",
351-
"label": "General Information",
352-
"order": 0,
353-
"row": 1,
354339
"col": 8,
355340
"fields": [
356341
{
@@ -362,129 +347,6 @@
362347
"element": "copy",
363348
"source": "scientificMetadata.run_number.value",
364349
"order": 1
365-
},
366-
{
367-
"element": "text",
368-
"source": "creationTime",
369-
"order": 2
370-
},
371-
{
372-
"element": "text",
373-
"source": "type",
374-
"order": 3
375-
},
376-
{
377-
"element": "text",
378-
"source": "datasetName",
379-
"order": 4
380-
},
381-
{
382-
"element": "tag",
383-
"source": "keywords",
384-
"order": 5
385-
}
386-
]
387-
},
388-
{
389-
"type": "attachments",
390-
"label": "Gallery",
391-
"order": 1,
392-
"col": 2,
393-
"row": 2,
394-
"options": {
395-
"limit": 5,
396-
"size": "medium"
397-
}
398-
},
399-
{
400-
"type": "regular",
401-
"label": "Contact Information",
402-
"order": 2,
403-
"col": 2,
404-
"row": 1,
405-
"fields": [
406-
{
407-
"element": "text",
408-
"source": "principalInvestigator",
409-
"order": 0
410-
},
411-
{
412-
"element": "linky",
413-
"source": "contactEmail",
414-
"order": 1
415-
}
416-
]
417-
},
418-
{
419-
"type": "regular",
420-
"label": "Files Information",
421-
"order": 3,
422-
"col": 2,
423-
"row": 1,
424-
"fields": [
425-
{
426-
"element": "text",
427-
"source": "scientificMetadata.runnumber",
428-
"order": 0
429-
},
430-
{
431-
"element": "text",
432-
"source": "sourceFolderHost",
433-
"order": 1
434-
},
435-
{
436-
"element": "text",
437-
"source": "numberOfFiles",
438-
"order": 2
439-
},
440-
{
441-
"element": "text",
442-
"source": "size",
443-
"order": 3
444-
},
445-
{
446-
"element": "text",
447-
"source": "numberOfFilesArchived",
448-
"order": 4
449-
},
450-
{
451-
"element": "text",
452-
"source": "packedSize",
453-
"order": 5
454-
}
455-
]
456-
},
457-
{
458-
"type": "regular",
459-
"label": "Related Documents",
460-
"order": 4,
461-
"col": 4,
462-
"row": 1,
463-
"fields": [
464-
{
465-
"element": "internalLink",
466-
"source": "proposalIds",
467-
"order": 0
468-
},
469-
{
470-
"element": "internalLink",
471-
"source": "instrumentIds",
472-
"order": 1
473-
},
474-
{
475-
"element": "tag",
476-
"source": "sampleIds",
477-
"order": 2
478-
},
479-
{
480-
"element": "tag",
481-
"source": "inputDatasets",
482-
"order": 3
483-
},
484-
{
485-
"element": "internalLink",
486-
"source": "creationLocation",
487-
"order": 4
488350
}
489351
]
490352
},
@@ -496,7 +358,7 @@
496358
"row": 1,
497359
"options": {
498360
"limit": 2,
499-
"size": "small"
361+
"size": "large"
500362
}
501363
},
502364
{
@@ -506,25 +368,6 @@
506368
"order": 6,
507369
"col": 9,
508370
"row": 1
509-
},
510-
{
511-
"type": "scientificMetadata",
512-
"label": "Scientific Metadata JSON",
513-
"viewMode": "json",
514-
"order": 6
515-
},
516-
{
517-
"type": "scientificMetadata",
518-
"label": "Scientific Metadata Tree",
519-
"viewMode": "tree",
520-
"order": 6
521-
},
522-
{
523-
"type": "datasetJsonView",
524-
"label": "Dataset JsonView",
525-
"order": 7,
526-
"col": 10,
527-
"row": 2
528371
}
529372
]
530373
},
Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,58 @@
1-
import { Body, Controller, Get, Param, Put, Req } from "@nestjs/common";
2-
import { ApiTags } from "@nestjs/swagger";
1+
import {
2+
Body,
3+
Controller,
4+
Get,
5+
Param,
6+
Put,
7+
Req,
8+
UseGuards,
9+
} from "@nestjs/common";
10+
import { ApiBearerAuth, ApiBody, ApiTags } from "@nestjs/swagger";
311
import { Request } from "express";
412
import { AllowAny } from "src/auth/decorators/allow-any.decorator";
513
import { JWTUser } from "src/auth/interfaces/jwt-user.interface";
614
import { OutputRuntimeConfigDto } from "./dto/runtime-config.dto";
715
import { RuntimeConfigService } from "./runtime-config.service";
8-
16+
import { PoliciesGuard } from "src/casl/guards/policies.guard";
17+
import { Action } from "src/casl/action.enum";
18+
import { AppAbility } from "src/casl/casl-ability.factory";
19+
import { CheckPolicies } from "src/casl/decorators/check-policies.decorator";
20+
import { RuntimeConfig } from "./schemas/runtime-config.schema";
21+
@ApiBearerAuth()
922
@ApiTags("runtime-config")
1023
@Controller("runtime-config")
1124
export class RuntimeConfigController {
1225
constructor(private readonly runtimeConfigService: RuntimeConfigService) {}
1326

1427
@AllowAny()
15-
@Get("data")
28+
@Get("data/:id")
1629
async getConfig(
1730
@Param("id") id: string,
1831
): Promise<OutputRuntimeConfigDto | null> {
19-
return this.runtimeConfigService.getConfig(id);
32+
const config = await this.runtimeConfigService.getConfig(id);
33+
34+
return config;
2035
}
2136

22-
@Put("data")
37+
@UseGuards(PoliciesGuard)
38+
@CheckPolicies("runtimeconfig", (ability: AppAbility) =>
39+
ability.can(Action.Update, RuntimeConfig),
40+
)
41+
@Put("data/:id")
42+
@ApiBody({
43+
type: Object,
44+
description: "Runtime config object",
45+
})
2346
async updateConfig(
2447
@Req() request: Request,
2548
@Param("id") id: string,
2649
@Body() config: Record<string, unknown>,
27-
): Promise<void> {
50+
): Promise<OutputRuntimeConfigDto | null> {
2851
const user: JWTUser = request.user as JWTUser;
29-
await this.runtimeConfigService.updateConfig(id, config, user.username);
52+
return await this.runtimeConfigService.updateConfig(
53+
id,
54+
config,
55+
user.username,
56+
);
3057
}
3158
}

src/runtime-config/runtime-config.module.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,35 @@ import {
66
RuntimeConfig,
77
RuntimeConfigSchema,
88
} from "./schemas/runtime-config.schema";
9+
import {
10+
GenericHistory,
11+
GenericHistorySchema,
12+
} from "src/common/schemas/generic-history.schema";
13+
import { ConfigModule, ConfigService } from "@nestjs/config";
14+
import { CaslModule } from "src/casl/casl.module";
15+
import { applyHistoryPluginOnce } from "src/common/mongoose/plugins/history.plugin.util";
916

1017
@Module({
1118
imports: [
19+
CaslModule,
20+
ConfigModule,
1221
MongooseModule.forFeature([
22+
{
23+
name: GenericHistory.name,
24+
schema: GenericHistorySchema,
25+
},
26+
]),
27+
MongooseModule.forFeatureAsync([
1328
{
1429
name: RuntimeConfig.name,
15-
schema: RuntimeConfigSchema,
30+
imports: [ConfigModule],
31+
inject: [ConfigService],
32+
useFactory: (configService: ConfigService) => {
33+
const schema = RuntimeConfigSchema;
34+
applyHistoryPluginOnce(schema, configService);
35+
36+
return schema;
37+
},
1638
},
1739
]),
1840
],

0 commit comments

Comments
 (0)