@j-schreiber/sf-cli-security-audit 0.15.0 → 0.16.1
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/README.md +17 -8
- package/lib/commands/org/scan/user-perms.d.ts +3 -0
- package/lib/commands/org/scan/user-perms.js +32 -1
- package/lib/commands/org/scan/user-perms.js.map +1 -1
- package/lib/libs/conf-init/defaultClassifications.js +10 -42
- package/lib/libs/conf-init/defaultClassifications.js.map +1 -1
- package/lib/libs/conf-init/init.types.d.ts +0 -7
- package/lib/libs/conf-init/init.types.js +0 -1
- package/lib/libs/conf-init/init.types.js.map +1 -1
- package/lib/libs/quick-scan/types.d.ts +7 -0
- package/lib/libs/quick-scan/userPermissionScanner.d.ts +3 -0
- package/lib/libs/quick-scan/userPermissionScanner.js +63 -14
- package/lib/libs/quick-scan/userPermissionScanner.js.map +1 -1
- package/lib/salesforce/describes/orgDescribe.d.ts +29 -0
- package/lib/salesforce/describes/orgDescribe.js +91 -0
- package/lib/salesforce/describes/orgDescribe.js.map +1 -0
- package/lib/salesforce/describes/orgDescribe.types.d.ts +11 -0
- package/lib/salesforce/describes/orgDescribe.types.js +2 -0
- package/lib/salesforce/describes/orgDescribe.types.js.map +1 -0
- package/lib/salesforce/index.d.ts +1 -0
- package/lib/salesforce/index.js +1 -0
- package/lib/salesforce/index.js.map +1 -1
- package/lib/salesforce/repositories/users/user.types.js +1 -1
- package/lib/salesforce/repositories/users/user.types.js.map +1 -1
- package/messages/org.scan.user-perms.md +13 -1
- package/oclif.manifest.json +10 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Security Audit Engine (SAE)
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
4
|
<a href="https://www.npmjs.com/package/@j-schreiber/sf-cli-security-audit"><img src="https://img.shields.io/npm/v/@j-schreiber/sf-cli-security-audit.svg?logo=npm" alt="NPM version"/></a>
|
|
5
5
|
<a href="https://github.com/j-schreiber/js-sf-cli-security-audit/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-blue" alt="License"></a>
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
|
+
A plugin for the sf CLI to perform automated security audits.
|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
|
|
8
12
|
> [!IMPORTANT]\
|
|
9
13
|
> The SAE is still in beta and under active development. Command signatures, results report format, and directory structures can change.
|
|
10
14
|
|
|
@@ -85,7 +89,7 @@ FLAG DESCRIPTIONS
|
|
|
85
89
|
essentially control, if a permission is allowed in a certain profile / permission set.
|
|
86
90
|
```
|
|
87
91
|
|
|
88
|
-
_See code: [src/commands/org/audit/init.ts](https://github.com/j-schreiber/js-sf-cli-security-audit/blob/v0.
|
|
92
|
+
_See code: [src/commands/org/audit/init.ts](https://github.com/j-schreiber/js-sf-cli-security-audit/blob/v0.16.1/src/commands/org/audit/init.ts)_
|
|
89
93
|
|
|
90
94
|
## `sf org audit run`
|
|
91
95
|
|
|
@@ -130,7 +134,7 @@ FLAG DESCRIPTIONS
|
|
|
130
134
|
never truncated.
|
|
131
135
|
```
|
|
132
136
|
|
|
133
|
-
_See code: [src/commands/org/audit/run.ts](https://github.com/j-schreiber/js-sf-cli-security-audit/blob/v0.
|
|
137
|
+
_See code: [src/commands/org/audit/run.ts](https://github.com/j-schreiber/js-sf-cli-security-audit/blob/v0.16.1/src/commands/org/audit/run.ts)_
|
|
134
138
|
|
|
135
139
|
## `sf org scan user-perms`
|
|
136
140
|
|
|
@@ -138,9 +142,10 @@ Performs a quick scan for specific user permissions.
|
|
|
138
142
|
|
|
139
143
|
```
|
|
140
144
|
USAGE
|
|
141
|
-
$ sf org scan user-perms -n <value>... -o <value> [--json] [--flags-dir <value>] [--api-version <value>]
|
|
145
|
+
$ sf org scan user-perms -n <value>... -o <value> [--json] [--flags-dir <value>] [--api-version <value>] [-d]
|
|
142
146
|
|
|
143
147
|
FLAGS
|
|
148
|
+
-d, --deep-scan Include all user permission assignments.
|
|
144
149
|
-n, --name=<value>... (required) One or more permissions to be searched for.
|
|
145
150
|
-o, --target-org=<value> (required) The target org to scan.
|
|
146
151
|
--api-version=<value> Override the api version used for api requests made by this command
|
|
@@ -161,15 +166,19 @@ EXAMPLES
|
|
|
161
166
|
$ sf org scan user-perms -o MyTargetOrg -n AuthorApex -n ModifyMetadata
|
|
162
167
|
|
|
163
168
|
FLAG DESCRIPTIONS
|
|
169
|
+
-d, --deep-scan Include all user permission assignments.
|
|
170
|
+
|
|
171
|
+
Searches the profile and all assigned permission sets for active users on the target org. A user can be listed
|
|
172
|
+
multiple times if they receive a permission from different sources (e.g. a profile and a permission set).
|
|
173
|
+
|
|
164
174
|
-n, --name=<value>... One or more permissions to be searched for.
|
|
165
175
|
|
|
166
|
-
You can specify any valid user permission on your org, such as "AuthorApex", "CustomizeApplication" or "ViewSetup".
|
|
176
|
+
You can specify any valid user permission on your org, such as "AuthorApex", "CustomizeApplication", or "ViewSetup".
|
|
167
177
|
If you are unsure what permissions are available on your org, initialise a new audit config and check the created
|
|
168
|
-
userPermissions.yml.
|
|
169
|
-
retun 0 results).
|
|
178
|
+
userPermissions.yml.
|
|
170
179
|
```
|
|
171
180
|
|
|
172
|
-
_See code: [src/commands/org/scan/user-perms.ts](https://github.com/j-schreiber/js-sf-cli-security-audit/blob/v0.
|
|
181
|
+
_See code: [src/commands/org/scan/user-perms.ts](https://github.com/j-schreiber/js-sf-cli-security-audit/blob/v0.16.1/src/commands/org/scan/user-perms.ts)_
|
|
173
182
|
|
|
174
183
|
<!-- commandsstop -->
|
|
175
184
|
|
|
@@ -10,11 +10,14 @@ export default class OrgUserPermScan extends SfCommand<OrgUserPermScanResult> {
|
|
|
10
10
|
name: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
|
|
11
11
|
'target-org': import("@oclif/core/interfaces").OptionFlag<import("@salesforce/core").Org, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
12
|
'api-version': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
'deep-scan': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
14
|
};
|
|
14
15
|
run(): Promise<OrgUserPermScanResult>;
|
|
15
16
|
private reportProgress;
|
|
17
|
+
private reportWarning;
|
|
16
18
|
private print;
|
|
17
19
|
private printSummary;
|
|
18
20
|
private printPermissionResults;
|
|
21
|
+
private printUserAssignments;
|
|
19
22
|
}
|
|
20
23
|
export declare function isEntityStatus(cls: unknown): cls is EntityScanStatus;
|
|
@@ -22,14 +22,21 @@ export default class OrgUserPermScan extends SfCommand {
|
|
|
22
22
|
required: true,
|
|
23
23
|
}),
|
|
24
24
|
'api-version': Flags.orgApiVersion(),
|
|
25
|
+
'deep-scan': Flags.boolean({
|
|
26
|
+
summary: messages.getMessage('flags.deep-scan.summary'),
|
|
27
|
+
description: messages.getMessage('flags.deep-scan.description'),
|
|
28
|
+
char: 'd',
|
|
29
|
+
}),
|
|
25
30
|
};
|
|
26
31
|
async run() {
|
|
27
32
|
const { flags } = await this.parse(OrgUserPermScan);
|
|
28
33
|
const scanner = new UserPermissionScanner();
|
|
29
34
|
scanner.on('progress', this.reportProgress);
|
|
35
|
+
scanner.on('permissionNotFound', this.reportWarning);
|
|
30
36
|
const result = await scanner.quickScan({
|
|
31
37
|
targetOrg: flags['target-org'].getConnection(flags['api-version']),
|
|
32
38
|
permissions: flags.name,
|
|
39
|
+
deepScan: flags['deep-scan'],
|
|
33
40
|
});
|
|
34
41
|
this.print(result);
|
|
35
42
|
return result;
|
|
@@ -51,10 +58,14 @@ export default class OrgUserPermScan extends SfCommand {
|
|
|
51
58
|
this.log();
|
|
52
59
|
}
|
|
53
60
|
};
|
|
61
|
+
reportWarning = (event) => {
|
|
62
|
+
this.warn(messages.createWarning('PermissionNotFound', [event.permissionName]));
|
|
63
|
+
};
|
|
54
64
|
print(result) {
|
|
55
65
|
this.printSummary(result);
|
|
56
66
|
Object.entries(result.permissions).forEach(([permName, permResult]) => {
|
|
57
67
|
this.printPermissionResults(permName, permResult);
|
|
68
|
+
this.printUserAssignments(permName, permResult.users);
|
|
58
69
|
});
|
|
59
70
|
}
|
|
60
71
|
printSummary(result) {
|
|
@@ -64,9 +75,12 @@ export default class OrgUserPermScan extends SfCommand {
|
|
|
64
75
|
permissionName,
|
|
65
76
|
profiles: permResult.profiles.length,
|
|
66
77
|
permissionSets: permResult.permissionSets.length,
|
|
78
|
+
...(permResult.users ? { users: permResult.users.length } : undefined),
|
|
67
79
|
});
|
|
68
80
|
});
|
|
69
|
-
|
|
81
|
+
if (data.length > 0) {
|
|
82
|
+
this.table({ data, title: '=== Summary ===', titleOptions: { bold: true } });
|
|
83
|
+
}
|
|
70
84
|
}
|
|
71
85
|
printPermissionResults(permissionName, result) {
|
|
72
86
|
const data = [];
|
|
@@ -80,6 +94,23 @@ export default class OrgUserPermScan extends SfCommand {
|
|
|
80
94
|
this.table({ data, title: permissionName, titleOptions: { underline: true } });
|
|
81
95
|
}
|
|
82
96
|
}
|
|
97
|
+
printUserAssignments(permName, data) {
|
|
98
|
+
if (!data || data.length === 0) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
data.sort((a, b) => {
|
|
102
|
+
const byUser = a.username.localeCompare(b.username);
|
|
103
|
+
if (byUser !== 0) {
|
|
104
|
+
return byUser;
|
|
105
|
+
}
|
|
106
|
+
const byType = b.type.localeCompare(a.type);
|
|
107
|
+
if (byType !== 0) {
|
|
108
|
+
return byType;
|
|
109
|
+
}
|
|
110
|
+
return a.source.localeCompare(b.source);
|
|
111
|
+
});
|
|
112
|
+
this.table({ title: `${permName} (Assignments)`, data });
|
|
113
|
+
}
|
|
83
114
|
}
|
|
84
115
|
export function isEntityStatus(cls) {
|
|
85
116
|
return cls.total !== undefined && cls.resolved !== undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-perms.js","sourceRoot":"","sources":["../../../../src/commands/org/scan/user-perms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,
|
|
1
|
+
{"version":3,"file":"user-perms.js","sourceRoot":"","sources":["../../../../src/commands/org/scan/user-perms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,qBAIN,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,oCAAoC,EAAE,qBAAqB,CAAC,CAAC;AAIpG,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,SAAgC;IACpE,MAAM,CAAU,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,CAAU,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACjE,MAAM,CAAU,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAE5D,MAAM,CAAU,KAAK,GAAG;QAC7B,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;YACjB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,oBAAoB,CAAC;YAClD,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,wBAAwB,CAAC;YAC1D,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,IAAI;SACf,CAAC;QACF,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC;YAC9B,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,0BAA0B,CAAC;YACxD,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,IAAI;SACf,CAAC;QACF,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE;QACpC,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC;YACzB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,yBAAyB,CAAC;YACvD,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,6BAA6B,CAAC;YAC/D,IAAI,EAAE,GAAG;SACV,CAAC;KACH,CAAC;IAEK,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,IAAI,qBAAqB,EAAE,CAAC;QAC5C,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC5C,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC;YACrC,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAClE,WAAW,EAAE,KAAK,CAAC,IAAI;YACvB,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC;SAC7B,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACnB,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,cAAc,GAAG,CAAC,KAAsB,EAAQ,EAAE;QACxD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACjC,CAAC;QACD,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,EAAE;YACzD,IAAI,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC;gBACjC,QAAQ,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAK,YAAY,CAAC,QAAS,IAAI,YAAY,CAAC,KAAM,GAAG,CAAC,CAAC;YAC9F,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YACjC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACpB,IAAI,CAAC,UAAU,CACb,QAAQ,CAAC,UAAU,CAAC,gCAAgC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAC1G,CAAC;YACF,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,CAAC;IACH,CAAC,CAAC;IAEM,aAAa,GAAG,CAAC,KAA+B,EAAQ,EAAE;QAChE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,oBAAoB,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAClF,CAAC,CAAC;IAEM,KAAK,CAAC,MAAuB;QACnC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC1B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,EAAE;YACpE,IAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAClD,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,YAAY,CAAC,MAAuB;QAC1C,MAAM,IAAI,GAAgG,EAAE,CAAC;QAC7G,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,EAAE,UAAU,CAAC,EAAE,EAAE;YAC1E,IAAI,CAAC,IAAI,CAAC;gBACR,cAAc;gBACd,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,MAAM;gBACpC,cAAc,EAAE,UAAU,CAAC,cAAc,CAAC,MAAM;gBAChD,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;aACvE,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAEO,sBAAsB,CAAC,cAAsB,EAAE,MAA4B;QACjF,MAAM,IAAI,GAAgD,EAAE,CAAC;QAC7D,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE;YACrC,IAAI,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE;YAC3C,IAAI,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;IAEO,oBAAoB,CAAC,QAAgB,EAAE,IAAmC;QAChF,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACjB,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YACpD,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjB,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC5C,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjB,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,OAAO,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,QAAQ,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;;AAGH,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,OAAQ,GAAwB,CAAC,KAAK,KAAK,SAAS,IAAK,GAAwB,CAAC,QAAQ,KAAK,SAAS,CAAC;AAC3G,CAAC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { PermissionRiskLevel, UserPrivilegeLevel } from '../audit-engine/index.js';
|
|
2
|
-
import { PermissionSets, Profiles, Users } from '../../salesforce/index.js';
|
|
2
|
+
import { OrgDescribe, PermissionSets, Profiles, Users } from '../../salesforce/index.js';
|
|
3
3
|
import { loadPreset } from './presets.js';
|
|
4
|
-
import { CUSTOM_PERMS_QUERY, } from './init.types.js';
|
|
5
4
|
export const ClassificationInitDefinitions = {
|
|
6
5
|
userPermissions: {
|
|
7
6
|
initialiser: initUserPermissions,
|
|
@@ -20,15 +19,14 @@ export const ClassificationInitDefinitions = {
|
|
|
20
19
|
},
|
|
21
20
|
};
|
|
22
21
|
async function initUserPermissions(con, preset) {
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const allPerms = { ...describePerms, ...assignedPerms };
|
|
22
|
+
const orgManager = new OrgDescribe(con);
|
|
23
|
+
const userPerms = await orgManager.getUserPermissions();
|
|
26
24
|
const presConfig = loadPreset(preset);
|
|
27
|
-
const perms = presConfig.classifyUserPermissions(
|
|
25
|
+
const perms = presConfig.classifyUserPermissions(userPerms);
|
|
28
26
|
perms.sort(classificationSorter);
|
|
29
27
|
const result = { permissions: {} };
|
|
30
28
|
perms.forEach((perm) => (result.permissions[perm.name] = {
|
|
31
|
-
label:
|
|
29
|
+
label: perm.label,
|
|
32
30
|
classification: perm.classification,
|
|
33
31
|
reason: perm.reason,
|
|
34
32
|
}));
|
|
@@ -36,13 +34,13 @@ async function initUserPermissions(con, preset) {
|
|
|
36
34
|
}
|
|
37
35
|
async function initCustomPermissions(con) {
|
|
38
36
|
const result = { permissions: {} };
|
|
39
|
-
const
|
|
40
|
-
|
|
37
|
+
const orgManager = new OrgDescribe(con);
|
|
38
|
+
const customPerms = await orgManager.getCustomPermissions();
|
|
39
|
+
if (customPerms.length === 0) {
|
|
41
40
|
return undefined;
|
|
42
41
|
}
|
|
43
|
-
const perms = customPerms.
|
|
44
|
-
|
|
45
|
-
label: cp.MasterLabel,
|
|
42
|
+
const perms = customPerms.map((cp) => ({
|
|
43
|
+
...cp,
|
|
46
44
|
classification: PermissionRiskLevel.UNKNOWN,
|
|
47
45
|
}));
|
|
48
46
|
perms.forEach((perm) => (result.permissions[perm.name] = {
|
|
@@ -83,34 +81,4 @@ function resolveRiskLevelOrdinalValue(value) {
|
|
|
83
81
|
return Object.keys(PermissionRiskLevel).indexOf(value.toUpperCase());
|
|
84
82
|
}
|
|
85
83
|
const classificationSorter = (a, b) => resolveRiskLevelOrdinalValue(a.classification) - resolveRiskLevelOrdinalValue(b.classification);
|
|
86
|
-
async function parsePermsFromDescribe(con) {
|
|
87
|
-
const permSet = await con.describe('PermissionSet');
|
|
88
|
-
const describeAvailablePerms = {};
|
|
89
|
-
permSet.fields
|
|
90
|
-
.filter((field) => field.name.startsWith('Permissions'))
|
|
91
|
-
.forEach((field) => {
|
|
92
|
-
const permName = field.name.replace('Permissions', '');
|
|
93
|
-
describeAvailablePerms[permName] = {
|
|
94
|
-
label: field.label,
|
|
95
|
-
name: permName,
|
|
96
|
-
};
|
|
97
|
-
});
|
|
98
|
-
return describeAvailablePerms;
|
|
99
|
-
}
|
|
100
|
-
async function getUserPermsFromProfiles(con) {
|
|
101
|
-
const assignedPerms = {};
|
|
102
|
-
const profilesRepo = new Profiles(con);
|
|
103
|
-
const profiles = await profilesRepo.resolve({ withMetadata: true });
|
|
104
|
-
for (const profile of profiles.values()) {
|
|
105
|
-
if (profile.metadata) {
|
|
106
|
-
profile.metadata.userPermissions.forEach((userPerm) => {
|
|
107
|
-
assignedPerms[userPerm.name] = { name: userPerm.name };
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return assignedPerms;
|
|
112
|
-
}
|
|
113
|
-
function sanitiseLabel(rawLabel) {
|
|
114
|
-
return rawLabel?.replaceAll(/[ \t]+$|[\r\n]+/g, '');
|
|
115
|
-
}
|
|
116
84
|
//# sourceMappingURL=defaultClassifications.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultClassifications.js","sourceRoot":"","sources":["../../../src/libs/conf-init/defaultClassifications.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACpG,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"defaultClassifications.js","sourceRoot":"","sources":["../../../src/libs/conf-init/defaultClassifications.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACpG,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAc1C,MAAM,CAAC,MAAM,6BAA6B,GAAsD;IAC9F,eAAe,EAAE;QACf,WAAW,EAAE,mBAAmB;KACjC;IACD,iBAAiB,EAAE;QACjB,WAAW,EAAE,qBAAqB;KACnC;IACD,QAAQ,EAAE;QACR,WAAW,EAAE,YAAY;KAC1B;IACD,cAAc,EAAE;QACd,WAAW,EAAE,kBAAkB;KAChC;IACD,KAAK,EAAE;QACL,WAAW,EAAE,SAAS;KACvB;CACF,CAAC;AAEF,KAAK,UAAU,mBAAmB,CAAC,GAAe,EAAE,MAAyB;IAC3E,MAAM,UAAU,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,kBAAkB,EAAE,CAAC;IACxD,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,UAAU,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;IAC5D,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACjC,MAAM,MAAM,GAA8B,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC9D,KAAK,CAAC,OAAO,CACX,CAAC,IAAI,EAAE,EAAE,CACP,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC,CACL,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,GAAe;IAClD,MAAM,MAAM,GAA8B,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC9D,MAAM,UAAU,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,oBAAoB,EAAE,CAAC;IAC5D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACrC,GAAG,EAAE;QACL,cAAc,EAAE,mBAAmB,CAAC,OAAO;KAC5C,CAAC,CAAC,CAAC;IACJ,KAAK,CAAC,OAAO,CACX,CAAC,IAAI,EAAE,EAAE,CACP,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,cAAc,EAAE,IAAI,CAAC,cAAc;KACpC,CAAC,CACL,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,YAAwB;IAClD,MAAM,YAAY,GAAG,IAAI,QAAQ,CAAC,YAAY,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,CAAC;IAC9C,MAAM,OAAO,GAA2B,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACzD,KAAK,MAAM,WAAW,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC;IACvE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,YAAwB;IACxD,MAAM,YAAY,GAAG,IAAI,cAAc,CAAC,YAAY,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,MAAM,OAAO,GAA2B,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC;IAC/D,KAAK,MAAM,WAAW,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1C,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC;IAC7E,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,YAAwB;IAC/C,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;IACxC,MAAM,OAAO,GAAwB;QACnC,KAAK,EAAE,EAAE;KACV,CAAC;IACF,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE;QAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,kBAAkB,CAAC,aAAa,EAAE,CAAC;IAC1G,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,4BAA4B,CAAC,KAAa;IACjD,OAAO,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,oBAAoB,GAAG,CAAC,CAAgC,EAAE,CAAgC,EAAU,EAAE,CAC1G,4BAA4B,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,4BAA4B,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC"}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import z from 'zod';
|
|
2
|
-
import { Record } from '@jsforce/jsforce-node';
|
|
3
2
|
import { AuditConfigShape } from '../audit-engine/index.js';
|
|
4
3
|
type AuditClassifications = (typeof AuditConfigShape)['classifications']['files'];
|
|
5
|
-
export declare const CUSTOM_PERMS_QUERY = "SELECT Id,MasterLabel,DeveloperName FROM CustomPermission";
|
|
6
4
|
export type PermissionClassifications = z.infer<AuditClassifications['userPermissions']['schema']>;
|
|
7
5
|
export type NamedPermissionClassification = PermissionClassifications['permissions']['string'] & {
|
|
8
6
|
name: string;
|
|
@@ -11,11 +9,6 @@ export type UnclassifiedPerm = Omit<NamedPermissionClassification, 'classificati
|
|
|
11
9
|
export type ProfileClassifications = z.infer<AuditClassifications['profiles']['schema']>;
|
|
12
10
|
export type PermsetClassifications = z.infer<AuditClassifications['permissionSets']['schema']>;
|
|
13
11
|
export type UserClassifications = z.infer<AuditClassifications['users']['schema']>;
|
|
14
|
-
export type SfCustomPermission = Record & {
|
|
15
|
-
Id: string;
|
|
16
|
-
MasterLabel: string;
|
|
17
|
-
DeveloperName: string;
|
|
18
|
-
};
|
|
19
12
|
export declare enum AuditInitPresets {
|
|
20
13
|
strict = "strict",
|
|
21
14
|
loose = "loose",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.types.js","sourceRoot":"","sources":["../../../src/libs/conf-init/init.types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.types.js","sourceRoot":"","sources":["../../../src/libs/conf-init/init.types.ts"],"names":[],"mappings":"AAYA,MAAM,CAAN,IAAY,gBAIX;AAJD,WAAY,gBAAgB;IAC1B,qCAAiB,CAAA;IACjB,mCAAe,CAAA;IACf,iCAAa,CAAA;AACf,CAAC,EAJW,gBAAgB,KAAhB,gBAAgB,QAI3B"}
|
|
@@ -10,8 +10,15 @@ export type QuickScanPermissionResult = {
|
|
|
10
10
|
export type PermissionScanResult = {
|
|
11
11
|
profiles: string[];
|
|
12
12
|
permissionSets: string[];
|
|
13
|
+
users?: UserPermissionAssignment[];
|
|
14
|
+
};
|
|
15
|
+
export type UserPermissionAssignment = {
|
|
16
|
+
username: string;
|
|
17
|
+
source: string;
|
|
18
|
+
type: 'Permission Set' | 'Profile';
|
|
13
19
|
};
|
|
14
20
|
export type QuickScanOptions = {
|
|
15
21
|
targetOrg: Connection;
|
|
16
22
|
permissions: string[];
|
|
23
|
+
deepScan: boolean;
|
|
17
24
|
};
|
|
@@ -11,6 +11,9 @@ export type EntityScanStatus = {
|
|
|
11
11
|
resolved?: number;
|
|
12
12
|
status?: string;
|
|
13
13
|
};
|
|
14
|
+
export type PermissionResolveWarning = {
|
|
15
|
+
permissionName: string;
|
|
16
|
+
};
|
|
14
17
|
export default class UserPermissionScanner extends EventEmitter {
|
|
15
18
|
private status;
|
|
16
19
|
constructor();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
|
-
import { PermissionSets, Profiles } from '../../salesforce/index.js';
|
|
2
|
+
import { OrgDescribe, PermissionSets, Profiles, Users } from '../../salesforce/index.js';
|
|
3
3
|
export default class UserPermissionScanner extends EventEmitter {
|
|
4
4
|
status = {
|
|
5
5
|
profiles: {},
|
|
@@ -12,30 +12,49 @@ export default class UserPermissionScanner extends EventEmitter {
|
|
|
12
12
|
}
|
|
13
13
|
async quickScan(opts) {
|
|
14
14
|
this.emitProgress({ status: 'Pending' });
|
|
15
|
-
const
|
|
15
|
+
const org = new OrgDescribe(opts.targetOrg);
|
|
16
|
+
const scannedEntities = await this.resolveEntities(opts);
|
|
16
17
|
const scanResult = {
|
|
17
18
|
permissions: {},
|
|
18
19
|
scannedProfiles: Object.keys(scannedEntities.profiles),
|
|
19
20
|
scannedPermissionSets: Object.keys(scannedEntities.permissionSets),
|
|
20
21
|
};
|
|
21
|
-
opts.permissions
|
|
22
|
+
for (const permName of opts.permissions) {
|
|
23
|
+
// org caches async calls, so this is okay
|
|
24
|
+
// eslint-disable-next-line no-await-in-loop
|
|
25
|
+
if (!(await org.isValid(permName))) {
|
|
26
|
+
this.emit('permissionNotFound', {
|
|
27
|
+
permissionName: permName,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
22
30
|
const profiles = findGrantingEntities(permName, scannedEntities.profiles);
|
|
23
31
|
const permissionSets = findGrantingEntities(permName, scannedEntities.permissionSets);
|
|
24
|
-
|
|
25
|
-
|
|
32
|
+
const users = findPermissionAssignments(permName, scannedEntities);
|
|
33
|
+
if (profiles.length > 0 || permissionSets.length > 0) {
|
|
34
|
+
scanResult.permissions[permName] = { permissionSets, profiles, users };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
26
37
|
this.emitProgress({ status: 'Completed' });
|
|
27
38
|
return scanResult;
|
|
28
39
|
}
|
|
29
|
-
async resolveEntities(
|
|
40
|
+
async resolveEntities(opts) {
|
|
30
41
|
const promises = [];
|
|
31
42
|
this.emitProgress({ status: 'In Progress' });
|
|
32
|
-
promises.push(this.resolveProfiles(targetOrg));
|
|
33
|
-
promises.push(this.resolvePermissionSets(targetOrg));
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
promises.push(this.resolveProfiles(opts.targetOrg));
|
|
44
|
+
promises.push(this.resolvePermissionSets(opts.targetOrg));
|
|
45
|
+
if (opts.deepScan) {
|
|
46
|
+
const usersRepo = new Users(opts.targetOrg);
|
|
47
|
+
promises.push(usersRepo.resolve({ withLoginHistory: false, withPermissions: true, withPermissionsMetadata: false }));
|
|
48
|
+
}
|
|
49
|
+
const resolvedPromises = await Promise.all(promises);
|
|
50
|
+
const resolvedEntities = {
|
|
51
|
+
profiles: prepareIndizes(resolvedPromises[0]),
|
|
52
|
+
permissionSets: prepareIndizes(resolvedPromises[1]),
|
|
38
53
|
};
|
|
54
|
+
if (opts.deepScan) {
|
|
55
|
+
resolvedEntities.users = resolvedPromises[2];
|
|
56
|
+
}
|
|
57
|
+
return resolvedEntities;
|
|
39
58
|
}
|
|
40
59
|
async resolveProfiles(targetOrg) {
|
|
41
60
|
const profilesRepo = new Profiles(targetOrg);
|
|
@@ -66,11 +85,41 @@ export default class UserPermissionScanner extends EventEmitter {
|
|
|
66
85
|
this.emit('progress', structuredClone(this.status));
|
|
67
86
|
}
|
|
68
87
|
}
|
|
88
|
+
function prepareIndizes(entities) {
|
|
89
|
+
const result = {};
|
|
90
|
+
for (const [identifier, metadata] of Object.entries(entities)) {
|
|
91
|
+
result[identifier] = {
|
|
92
|
+
userPermissions: new Set(metadata.userPermissions.filter((perm) => perm.enabled).map((perm) => perm.name)),
|
|
93
|
+
customPermissions: new Set(metadata.customPermissions.filter((perm) => perm.enabled).map((perm) => perm.name)),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
function findPermissionAssignments(permName, scanContext) {
|
|
99
|
+
if (!scanContext.users) {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
const permAssignments = [];
|
|
103
|
+
for (const [username, userDetails] of scanContext.users.entries()) {
|
|
104
|
+
const profile = scanContext.profiles[userDetails.profileName];
|
|
105
|
+
if (profile && profile.userPermissions.has(permName)) {
|
|
106
|
+
permAssignments.push({ username, source: userDetails.profileName, type: 'Profile' });
|
|
107
|
+
}
|
|
108
|
+
if (userDetails.assignments) {
|
|
109
|
+
for (const permSetAss of userDetails.assignments) {
|
|
110
|
+
const permSet = scanContext.permissionSets[permSetAss.permissionSetIdentifier];
|
|
111
|
+
if (permSet && permSet.userPermissions.has(permName)) {
|
|
112
|
+
permAssignments.push({ username, source: permSetAss.permissionSetIdentifier, type: 'Permission Set' });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return permAssignments;
|
|
118
|
+
}
|
|
69
119
|
function findGrantingEntities(permName, resolvedEntities) {
|
|
70
120
|
const entities = new Set();
|
|
71
121
|
Object.entries(resolvedEntities).forEach(([entityName, metadata]) => {
|
|
72
|
-
|
|
73
|
-
if (userPerms.includes(permName)) {
|
|
122
|
+
if (metadata.userPermissions.has(permName)) {
|
|
74
123
|
entities.add(entityName);
|
|
75
124
|
}
|
|
76
125
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userPermissionScanner.js","sourceRoot":"","sources":["../../../src/libs/quick-scan/userPermissionScanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"userPermissionScanner.js","sourceRoot":"","sources":["../../../src/libs/quick-scan/userPermissionScanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Connection } from '@salesforce/core';
|
|
2
|
+
import { Permission } from './orgDescribe.types.js';
|
|
3
|
+
export default class OrgDescribe {
|
|
4
|
+
#private;
|
|
5
|
+
private con;
|
|
6
|
+
private customPermissions?;
|
|
7
|
+
constructor(con: Connection);
|
|
8
|
+
private get userPermissions();
|
|
9
|
+
/**
|
|
10
|
+
* Analyses describe information and metadata to initialise
|
|
11
|
+
* all permissions from the target org.
|
|
12
|
+
*
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
getUserPermissions(): Promise<Permission[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Checks if the permission is valid for the org.
|
|
18
|
+
*
|
|
19
|
+
* @param permissionName
|
|
20
|
+
*/
|
|
21
|
+
isValid(permissionName: string): Promise<boolean>;
|
|
22
|
+
/**
|
|
23
|
+
* Finds all custom permissions that exist on the target org.
|
|
24
|
+
*
|
|
25
|
+
* @returns
|
|
26
|
+
*/
|
|
27
|
+
getCustomPermissions(): Promise<Permission[]>;
|
|
28
|
+
private fetchUserPermissions;
|
|
29
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import Profiles from '../repositories/profiles/profiles.js';
|
|
2
|
+
import { CUSTOM_PERMS_QUERY } from './orgDescribe.types.js';
|
|
3
|
+
export default class OrgDescribe {
|
|
4
|
+
con;
|
|
5
|
+
customPermissions;
|
|
6
|
+
#userPermissions;
|
|
7
|
+
constructor(con) {
|
|
8
|
+
this.con = con;
|
|
9
|
+
}
|
|
10
|
+
get userPermissions() {
|
|
11
|
+
return (this.#userPermissions ??= this.fetchUserPermissions());
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Analyses describe information and metadata to initialise
|
|
15
|
+
* all permissions from the target org.
|
|
16
|
+
*
|
|
17
|
+
* @returns
|
|
18
|
+
*/
|
|
19
|
+
async getUserPermissions() {
|
|
20
|
+
const userPerms = await this.userPermissions;
|
|
21
|
+
return Array.from(userPerms.values());
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Checks if the permission is valid for the org.
|
|
25
|
+
*
|
|
26
|
+
* @param permissionName
|
|
27
|
+
*/
|
|
28
|
+
async isValid(permissionName) {
|
|
29
|
+
const userPerms = await this.userPermissions;
|
|
30
|
+
return userPerms.has(permissionName);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Finds all custom permissions that exist on the target org.
|
|
34
|
+
*
|
|
35
|
+
* @returns
|
|
36
|
+
*/
|
|
37
|
+
async getCustomPermissions() {
|
|
38
|
+
if (!this.customPermissions) {
|
|
39
|
+
this.customPermissions = new Map();
|
|
40
|
+
const customPerms = await this.con.query(CUSTOM_PERMS_QUERY);
|
|
41
|
+
if (customPerms.records.length > 0) {
|
|
42
|
+
for (const cp of customPerms.records) {
|
|
43
|
+
this.customPermissions.set(cp.DeveloperName, {
|
|
44
|
+
name: cp.DeveloperName,
|
|
45
|
+
label: cp.MasterLabel,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return Array.from(this.customPermissions.values());
|
|
51
|
+
}
|
|
52
|
+
async fetchUserPermissions() {
|
|
53
|
+
const describePerms = await parsePermsFromDescribe(this.con);
|
|
54
|
+
const assignedPerms = await getUserPermsFromProfiles(this.con);
|
|
55
|
+
return mergeMaps(assignedPerms, describePerms);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function mergeMaps(...permMaps) {
|
|
59
|
+
return new Map(permMaps.flatMap((m) => [...m]));
|
|
60
|
+
}
|
|
61
|
+
async function parsePermsFromDescribe(con) {
|
|
62
|
+
const permSet = await con.describe('PermissionSet');
|
|
63
|
+
const describeAvailablePerms = new Map();
|
|
64
|
+
permSet.fields
|
|
65
|
+
.filter((field) => field.name.startsWith('Permissions'))
|
|
66
|
+
.forEach((field) => {
|
|
67
|
+
const permName = field.name.replace('Permissions', '');
|
|
68
|
+
describeAvailablePerms.set(permName, {
|
|
69
|
+
label: sanitiseLabel(field.label),
|
|
70
|
+
name: permName,
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
return describeAvailablePerms;
|
|
74
|
+
}
|
|
75
|
+
async function getUserPermsFromProfiles(con) {
|
|
76
|
+
const assignedPerms = new Map();
|
|
77
|
+
const profilesRepo = new Profiles(con);
|
|
78
|
+
const profiles = await profilesRepo.resolve({ withMetadata: true });
|
|
79
|
+
for (const profile of profiles.values()) {
|
|
80
|
+
if (profile.metadata) {
|
|
81
|
+
profile.metadata.userPermissions.forEach((userPerm) => {
|
|
82
|
+
assignedPerms.set(userPerm.name, { name: userPerm.name, label: userPerm.name });
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return assignedPerms;
|
|
87
|
+
}
|
|
88
|
+
function sanitiseLabel(rawLabel) {
|
|
89
|
+
return rawLabel?.replaceAll(/[ \t]+$|[\r\n]+/g, '');
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=orgDescribe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orgDescribe.js","sourceRoot":"","sources":["../../../src/salesforce/describes/orgDescribe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Record } from '@jsforce/jsforce-node';
|
|
2
|
+
export declare const CUSTOM_PERMS_QUERY = "SELECT Id,MasterLabel,DeveloperName FROM CustomPermission";
|
|
3
|
+
export type Permission = {
|
|
4
|
+
name: string;
|
|
5
|
+
label?: string;
|
|
6
|
+
};
|
|
7
|
+
export type SfCustomPermission = Record & {
|
|
8
|
+
Id: string;
|
|
9
|
+
MasterLabel: string;
|
|
10
|
+
DeveloperName: string;
|
|
11
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orgDescribe.types.js","sourceRoot":"","sources":["../../../src/salesforce/describes/orgDescribe.types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAG,2DAA2D,CAAC"}
|
|
@@ -2,6 +2,7 @@ export { default as Users } from './repositories/users/users.js';
|
|
|
2
2
|
export { default as Profiles } from './repositories/profiles/profiles.js';
|
|
3
3
|
export { default as ConnectedApps } from './repositories/connected-apps/connected-apps.js';
|
|
4
4
|
export { default as PermissionSets } from './repositories/perm-sets/permission-sets.js';
|
|
5
|
+
export { default as OrgDescribe } from './describes/orgDescribe.js';
|
|
5
6
|
export type { User, ResolveUsersOptions } from './repositories/users/user.types.js';
|
|
6
7
|
export type { Profile } from './repositories/profiles/profile.types.js';
|
|
7
8
|
export type { ConnectedApp } from './repositories/connected-apps/connected-app.types.js';
|
package/lib/salesforce/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export { default as Users } from './repositories/users/users.js';
|
|
|
3
3
|
export { default as Profiles } from './repositories/profiles/profiles.js';
|
|
4
4
|
export { default as ConnectedApps } from './repositories/connected-apps/connected-apps.js';
|
|
5
5
|
export { default as PermissionSets } from './repositories/perm-sets/permission-sets.js';
|
|
6
|
+
export { default as OrgDescribe } from './describes/orgDescribe.js';
|
|
6
7
|
// MDAPI
|
|
7
8
|
export { default as MDAPI } from './mdapi/mdapi.js';
|
|
8
9
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/salesforce/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iDAAiD,CAAC;AAC3F,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,6CAA6C,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/salesforce/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iDAAiD,CAAC;AAC3F,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,6CAA6C,CAAC;AACxF,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAQpE,QAAQ;AACR,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -4,7 +4,7 @@ export const ResolveUsersOptionsSchema = z.object({
|
|
|
4
4
|
withLoginHistory: z.boolean().default(false),
|
|
5
5
|
/** Length of login history. Has no effect, if login history is false */
|
|
6
6
|
loginHistoryDaysToAnalyse: z.number().optional(),
|
|
7
|
-
/** Include profile and assigned permission sets */
|
|
7
|
+
/** Include name of profile and developer names of assigned permission sets */
|
|
8
8
|
withPermissions: z.boolean().default(false),
|
|
9
9
|
/** Adds metadata to permissions. Has no effect, if withPermissions is false */
|
|
10
10
|
withPermissionsMetadata: z.boolean().default(false),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.types.js","sourceRoot":"","sources":["../../../../src/salesforce/repositories/users/user.types.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AA+CpB,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,uCAAuC;IACvC,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC5C,wEAAwE;IACxE,yBAAyB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChD,
|
|
1
|
+
{"version":3,"file":"user.types.js","sourceRoot":"","sources":["../../../../src/salesforce/repositories/users/user.types.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AA+CpB,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,uCAAuC;IACvC,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC5C,wEAAwE;IACxE,yBAAyB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChD,8EAA8E;IAC9E,eAAe,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC3C,+EAA+E;IAC/E,uBAAuB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;CACpD,CAAC,CAAC"}
|
|
@@ -12,12 +12,20 @@ One or more permissions to be searched for.
|
|
|
12
12
|
|
|
13
13
|
# flags.name.description
|
|
14
14
|
|
|
15
|
-
You can specify any valid user permission on your org, such as "AuthorApex", "CustomizeApplication" or "ViewSetup". If you are unsure what permissions are available on your org, initialise a new audit config and check the created userPermissions.yml.
|
|
15
|
+
You can specify any valid user permission on your org, such as "AuthorApex", "CustomizeApplication", or "ViewSetup". If you are unsure what permissions are available on your org, initialise a new audit config and check the created userPermissions.yml.
|
|
16
16
|
|
|
17
17
|
# flags.target-org.summary
|
|
18
18
|
|
|
19
19
|
The target org to scan.
|
|
20
20
|
|
|
21
|
+
# flags.deep-scan.summary
|
|
22
|
+
|
|
23
|
+
Include all user permission assignments.
|
|
24
|
+
|
|
25
|
+
# flags.deep-scan.description
|
|
26
|
+
|
|
27
|
+
Searches the profile and all assigned permission sets for active users on the target org. A user can be listed multiple times if they receive a permission from different sources (e.g. a profile and a permission set).
|
|
28
|
+
|
|
21
29
|
# examples
|
|
22
30
|
|
|
23
31
|
- Search for multiple permissions on MyTargetOrg
|
|
@@ -27,3 +35,7 @@ The target org to scan.
|
|
|
27
35
|
# success.scanned-entities-count
|
|
28
36
|
|
|
29
37
|
Scanned %s profiles and %s permission sets.
|
|
38
|
+
|
|
39
|
+
# PermissionNotFound
|
|
40
|
+
|
|
41
|
+
Permission "%s" does not exist on the target org. Maybe you mistyped it?
|
package/oclif.manifest.json
CHANGED
|
@@ -205,7 +205,7 @@
|
|
|
205
205
|
},
|
|
206
206
|
"name": {
|
|
207
207
|
"char": "n",
|
|
208
|
-
"description": "You can specify any valid user permission on your org, such as \"AuthorApex\", \"CustomizeApplication\" or \"ViewSetup\". If you are unsure what permissions are available on your org, initialise a new audit config and check the created userPermissions.yml.
|
|
208
|
+
"description": "You can specify any valid user permission on your org, such as \"AuthorApex\", \"CustomizeApplication\", or \"ViewSetup\". If you are unsure what permissions are available on your org, initialise a new audit config and check the created userPermissions.yml.",
|
|
209
209
|
"name": "name",
|
|
210
210
|
"required": true,
|
|
211
211
|
"summary": "One or more permissions to be searched for.",
|
|
@@ -229,6 +229,14 @@
|
|
|
229
229
|
"hasDynamicHelp": false,
|
|
230
230
|
"multiple": false,
|
|
231
231
|
"type": "option"
|
|
232
|
+
},
|
|
233
|
+
"deep-scan": {
|
|
234
|
+
"char": "d",
|
|
235
|
+
"description": "Searches the profile and all assigned permission sets for active users on the target org. A user can be listed multiple times if they receive a permission from different sources (e.g. a profile and a permission set).",
|
|
236
|
+
"name": "deep-scan",
|
|
237
|
+
"summary": "Include all user permission assignments.",
|
|
238
|
+
"allowNo": false,
|
|
239
|
+
"type": "boolean"
|
|
232
240
|
}
|
|
233
241
|
},
|
|
234
242
|
"hasDynamicHelp": true,
|
|
@@ -259,5 +267,5 @@
|
|
|
259
267
|
]
|
|
260
268
|
}
|
|
261
269
|
},
|
|
262
|
-
"version": "0.
|
|
270
|
+
"version": "0.16.1"
|
|
263
271
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@j-schreiber/sf-cli-security-audit",
|
|
3
3
|
"description": "Salesforce CLI plugin to automate highly configurable security audits",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.16.1",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/j-schreiber/js-sf-cli-security-audit"
|