Skip to content

Commit 4c74a90

Browse files
committed
feat: ACL indexer
1 parent 6dd3170 commit 4c74a90

File tree

4 files changed

+131
-14
lines changed

4 files changed

+131
-14
lines changed

src/indexer/IndexManager.ts

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,22 @@ import { AutoloadNamespaceIndexData } from './autoload-namespace/AutoloadNamespa
1414
import { EventsIndexData } from './events/EventsIndexData';
1515
import Logger from 'util/Logger';
1616
import { IndexerKey } from 'types/indexer';
17+
import AclIndexer from './acl/AclIndexer';
18+
import { AclIndexData } from './acl/AclIndexData';
1719

18-
type IndexerInstance = DiIndexer | ModuleIndexer | AutoloadNamespaceIndexer | EventsIndexer;
20+
type IndexerInstance =
21+
| DiIndexer
22+
| ModuleIndexer
23+
| AutoloadNamespaceIndexer
24+
| EventsIndexer
25+
| AclIndexer;
1926

2027
type IndexerDataMap = {
2128
[DiIndexer.KEY]: DiIndexData;
2229
[ModuleIndexer.KEY]: ModuleIndexData;
2330
[AutoloadNamespaceIndexer.KEY]: AutoloadNamespaceIndexData;
2431
[EventsIndexer.KEY]: EventsIndexData;
32+
[AclIndexer.KEY]: AclIndexData;
2533
};
2634

2735
class IndexManager {
@@ -34,6 +42,7 @@ class IndexManager {
3442
new ModuleIndexer(),
3543
new AutoloadNamespaceIndexer(),
3644
new EventsIndexer(),
45+
new AclIndexer(),
3746
];
3847
this.indexStorage = new IndexStorage();
3948
}
@@ -148,23 +157,25 @@ class IndexManager {
148157
return undefined;
149158
}
150159

151-
if (id === DiIndexer.KEY) {
152-
return new DiIndexData(data) as IndexerDataMap[T];
153-
}
160+
switch (id) {
161+
case DiIndexer.KEY:
162+
return new DiIndexData(data) as IndexerDataMap[T];
154163

155-
if (id === ModuleIndexer.KEY) {
156-
return new ModuleIndexData(data) as IndexerDataMap[T];
157-
}
164+
case ModuleIndexer.KEY:
165+
return new ModuleIndexData(data) as IndexerDataMap[T];
158166

159-
if (id === AutoloadNamespaceIndexer.KEY) {
160-
return new AutoloadNamespaceIndexData(data) as IndexerDataMap[T];
161-
}
167+
case AutoloadNamespaceIndexer.KEY:
168+
return new AutoloadNamespaceIndexData(data) as IndexerDataMap[T];
162169

163-
if (id === EventsIndexer.KEY) {
164-
return new EventsIndexData(data) as IndexerDataMap[T];
165-
}
170+
case EventsIndexer.KEY:
171+
return new EventsIndexData(data) as IndexerDataMap[T];
172+
173+
case AclIndexer.KEY:
174+
return new AclIndexData(data) as IndexerDataMap[T];
166175

167-
return undefined;
176+
default:
177+
return undefined;
178+
}
168179
}
169180

170181
protected async indexFileInner(

src/indexer/acl/AclIndexData.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { Acl } from './types';
2+
import { AbstractIndexData } from 'indexer/AbstractIndexData';
3+
4+
export class AclIndexData extends AbstractIndexData<Acl[]> {}

src/indexer/acl/AclIndexer.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { RelativePattern, Uri } from 'vscode';
2+
import { XMLParser } from 'fast-xml-parser';
3+
import { get, map } from 'lodash-es';
4+
import { Indexer } from 'indexer/Indexer';
5+
import FileSystem from 'util/FileSystem';
6+
import { IndexerKey } from 'types/indexer';
7+
import { Acl } from './types';
8+
9+
interface Element {
10+
'@_id'?: string;
11+
'@_title'?: string;
12+
'@_description'?: string;
13+
'@_sortOrder'?: string;
14+
'@_disabled'?: string;
15+
resource?: Element[];
16+
}
17+
18+
export default class AclIndexer extends Indexer<Acl[]> {
19+
public static readonly KEY = 'acl';
20+
21+
private xmlParser: XMLParser;
22+
23+
public constructor() {
24+
super();
25+
26+
this.xmlParser = new XMLParser({
27+
ignoreAttributes: false,
28+
attributeNamePrefix: '@_',
29+
isArray: name => {
30+
return name === 'resource';
31+
},
32+
});
33+
}
34+
35+
public getVersion(): number {
36+
return 1;
37+
}
38+
39+
public getId(): IndexerKey {
40+
return AclIndexer.KEY;
41+
}
42+
43+
public getName(): string {
44+
return 'acl.xml';
45+
}
46+
47+
public getPattern(uri: Uri): RelativePattern {
48+
return new RelativePattern(uri, '**/etc/acl.xml');
49+
}
50+
51+
public async indexFile(uri: Uri): Promise<Acl[]> {
52+
const xml = await FileSystem.readFile(uri);
53+
54+
const parsed = this.xmlParser.parse(xml);
55+
56+
const events = get(parsed, 'config.acl.resources.resource', []);
57+
58+
const acls = [];
59+
60+
for (const event of events) {
61+
acls.push(...this.getResources(event, uri));
62+
}
63+
64+
return acls;
65+
}
66+
67+
private getResources(element: Element, uri: Uri): Acl[] {
68+
const parent = get(element, '@_id', undefined);
69+
const resources = get(element, 'resource', []);
70+
71+
const acls: Acl[] = [];
72+
73+
for (const resource of resources) {
74+
if (Array.isArray(resource.resource)) {
75+
acls.push(...this.getResources(resource, uri));
76+
}
77+
78+
if (resource['@_id'] && resource['@_title']) {
79+
acls.push({
80+
id: resource['@_id'],
81+
title: resource['@_title'],
82+
description: resource['@_description'],
83+
sortOrder: resource['@_sortOrder'] ? parseInt(resource['@_sortOrder'], 10) : undefined,
84+
disabled: resource['@_disabled'] === 'true',
85+
parent,
86+
path: uri.fsPath,
87+
});
88+
}
89+
}
90+
91+
return acls;
92+
}
93+
}

src/indexer/acl/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export interface Acl {
2+
id: string;
3+
path: string;
4+
title: string;
5+
description?: string;
6+
sortOrder?: number;
7+
disabled?: boolean;
8+
parent?: string;
9+
}

0 commit comments

Comments
 (0)