aws-iam-language-server 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -69,3 +69,4 @@ This language server will provide diagnostics for some IAM policy issues, includ
|
|
|
69
69
|
- ensuring `Sid` uniqueness within a policy document
|
|
70
70
|
- effect has a valid value
|
|
71
71
|
- defined actions are valid, or wildcards resolve to valid actions
|
|
72
|
+
- arn parts are valid (partition, region, account id)
|
|
@@ -1,7 +1,59 @@
|
|
|
1
|
+
import { isRegionValidForPartition, isValidPartition, partitions } from "../../lib/iam-policy/partitions.js";
|
|
1
2
|
import { ElementValidator } from "./base.js";
|
|
3
|
+
import { createDiagnostic } from "./utils.js";
|
|
4
|
+
const validPartitions = Object.keys(partitions);
|
|
5
|
+
const accountIdPattern = /^\d{12}$/;
|
|
6
|
+
function segmentRange(value, segmentIndex) {
|
|
7
|
+
const segments = value.text.split(':');
|
|
8
|
+
let offset = 0;
|
|
9
|
+
for (let i = 0; i < segmentIndex; i++) {
|
|
10
|
+
offset += segments[i].length + 1;
|
|
11
|
+
}
|
|
12
|
+
const startColumn = value.range.start.column + offset;
|
|
13
|
+
const endColumn = startColumn + segments[segmentIndex].length;
|
|
14
|
+
return {
|
|
15
|
+
start: { line: value.range.start.line, column: startColumn },
|
|
16
|
+
end: { line: value.range.start.line, column: endColumn },
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function validateArn(value) {
|
|
20
|
+
const text = value.text;
|
|
21
|
+
const diagnostics = [];
|
|
22
|
+
if (!text.startsWith('arn:'))
|
|
23
|
+
return [];
|
|
24
|
+
const segments = text.split(':');
|
|
25
|
+
if (segments.length > 1) {
|
|
26
|
+
const partition = segments[1];
|
|
27
|
+
if (partition === '') {
|
|
28
|
+
diagnostics.push(createDiagnostic('partition is required', segmentRange(value, 1)));
|
|
29
|
+
}
|
|
30
|
+
else if (partition !== '*' && !Object.keys(partitions).includes(partition)) {
|
|
31
|
+
diagnostics.push(createDiagnostic(`partition must be one of: ${[...validPartitions].join(',')}`, segmentRange(value, 1)));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (segments.length > 3) {
|
|
35
|
+
const partition = segments[1];
|
|
36
|
+
const region = segments[3];
|
|
37
|
+
if (isValidPartition(partition)) {
|
|
38
|
+
if (region !== '*' && region !== '' && !isRegionValidForPartition(partition, region)) {
|
|
39
|
+
diagnostics.push(createDiagnostic('invalid region for this partition', segmentRange(value, 3)));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (segments.length > 4) {
|
|
44
|
+
const account = segments[4];
|
|
45
|
+
if (account !== '*' && account !== '' && !accountIdPattern.test(account)) {
|
|
46
|
+
diagnostics.push(createDiagnostic('expected account id to be 12 digits', segmentRange(value, 4)));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return diagnostics;
|
|
50
|
+
}
|
|
2
51
|
export class ResourceValidator extends ElementValidator {
|
|
3
52
|
validate(entry) {
|
|
4
|
-
|
|
53
|
+
let diagnostics = super.validate(entry);
|
|
54
|
+
for (const value of entry.values) {
|
|
55
|
+
diagnostics = diagnostics.concat(validateArn(value));
|
|
56
|
+
}
|
|
5
57
|
return diagnostics;
|
|
6
58
|
}
|
|
7
59
|
}
|
|
@@ -114,3 +114,7 @@ export declare const partitions: {
|
|
|
114
114
|
}];
|
|
115
115
|
};
|
|
116
116
|
};
|
|
117
|
+
type Partition = keyof typeof partitions;
|
|
118
|
+
export declare function isValidPartition(input: string): input is Partition;
|
|
119
|
+
export declare function isRegionValidForPartition<T extends Partition>(partition: T, input: string): input is (typeof partitions)[T]['regions'][number]['id'];
|
|
120
|
+
export {};
|
|
@@ -49,3 +49,9 @@ export const partitions = {
|
|
|
49
49
|
],
|
|
50
50
|
},
|
|
51
51
|
};
|
|
52
|
+
export function isValidPartition(input) {
|
|
53
|
+
return Object.keys(partitions).includes(input);
|
|
54
|
+
}
|
|
55
|
+
export function isRegionValidForPartition(partition, input) {
|
|
56
|
+
return partitions[partition].regions.some((r) => r.id === input);
|
|
57
|
+
}
|