@j-schreiber/sf-cli-security-audit 0.19.3 → 0.20.0
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 +3 -3
- package/lib/commands/org/audit/init.d.ts +1 -1
- package/lib/commands/org/audit/init.js +8 -8
- package/lib/commands/org/audit/init.js.map +1 -1
- package/lib/commands/org/audit/run.js +4 -1
- package/lib/commands/org/audit/run.js.map +1 -1
- package/lib/libs/audit-engine/auditRun.d.ts +3 -4
- package/lib/libs/audit-engine/auditRun.js +21 -9
- package/lib/libs/audit-engine/auditRun.js.map +1 -1
- package/lib/libs/audit-engine/file-manager/fileManager.d.ts +5 -6
- package/lib/libs/audit-engine/file-manager/fileManager.js +34 -15
- package/lib/libs/audit-engine/file-manager/fileManager.js.map +1 -1
- package/lib/libs/audit-engine/file-manager/fileManager.types.d.ts +1 -0
- package/lib/libs/audit-engine/index.d.ts +72 -43
- package/lib/libs/audit-engine/registry/context.types.d.ts +6 -0
- package/lib/libs/audit-engine/registry/definitions.d.ts +73 -44
- package/lib/libs/audit-engine/registry/policies/permissionSets.js +1 -1
- package/lib/libs/audit-engine/registry/policies/permissionSets.js.map +1 -1
- package/lib/libs/audit-engine/registry/policies/profiles.js +1 -1
- package/lib/libs/audit-engine/registry/policies/profiles.js.map +1 -1
- package/lib/libs/audit-engine/registry/policies/users.js +1 -1
- package/lib/libs/audit-engine/registry/policies/users.js.map +1 -1
- package/lib/libs/audit-engine/registry/policy.js +2 -2
- package/lib/libs/audit-engine/registry/policy.js.map +1 -1
- package/lib/libs/audit-engine/registry/roles/roleManager.d.ts +3 -19
- package/lib/libs/audit-engine/registry/roles/roleManager.js +17 -29
- package/lib/libs/audit-engine/registry/roles/roleManager.js.map +1 -1
- package/lib/libs/audit-engine/registry/roles/roleManager.types.d.ts +21 -3
- package/lib/libs/audit-engine/registry/roles/userRole.d.ts +7 -6
- package/lib/libs/audit-engine/registry/roles/userRole.js +78 -31
- package/lib/libs/audit-engine/registry/roles/userRole.js.map +1 -1
- package/lib/libs/audit-engine/registry/rules/enforcePermissionPresets.js +5 -4
- package/lib/libs/audit-engine/registry/rules/enforcePermissionPresets.js.map +1 -1
- package/lib/libs/audit-engine/registry/rules/enforcePermissionsOnProfileLike.js +3 -3
- package/lib/libs/audit-engine/registry/rules/enforcePermissionsOnProfileLike.js.map +1 -1
- package/lib/libs/audit-engine/registry/rules/enforcePermissionsOnUser.js +4 -4
- package/lib/libs/audit-engine/registry/rules/enforcePermissionsOnUser.js.map +1 -1
- package/lib/libs/audit-engine/registry/shape/auditConfigShape.d.ts +71 -42
- package/lib/libs/audit-engine/registry/shape/auditConfigShape.js +26 -30
- package/lib/libs/audit-engine/registry/shape/auditConfigShape.js.map +1 -1
- package/lib/libs/audit-engine/registry/shape/schema.d.ts +77 -43
- package/lib/libs/audit-engine/registry/shape/schema.js +22 -20
- package/lib/libs/audit-engine/registry/shape/schema.js.map +1 -1
- package/lib/libs/audit-engine/registry/shape/shapeValidation.d.ts +3 -0
- package/lib/libs/audit-engine/registry/shape/shapeValidation.js +36 -7
- package/lib/libs/audit-engine/registry/shape/shapeValidation.js.map +1 -1
- package/lib/libs/conf-init/auditConfig.d.ts +1 -0
- package/lib/libs/conf-init/auditConfig.js +15 -10
- package/lib/libs/conf-init/auditConfig.js.map +1 -1
- package/lib/libs/conf-init/defaultClassifications.d.ts +4 -6
- package/lib/libs/conf-init/defaultClassifications.js +18 -28
- package/lib/libs/conf-init/defaultClassifications.js.map +1 -1
- package/lib/libs/conf-init/init.types.d.ts +7 -6
- package/lib/libs/conf-init/init.types.js.map +1 -1
- package/messages/auditShapeValidation.md +4 -0
- package/messages/org.audit.run.md +4 -0
- package/messages/rules.enforceClassificationPresets.md +4 -8
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
- package/lib/libs/audit-engine/registry/helpers/permissionsScanning.d.ts +0 -37
- package/lib/libs/audit-engine/registry/helpers/permissionsScanning.js +0 -81
- package/lib/libs/audit-engine/registry/helpers/permissionsScanning.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RuleRegistry, PolicyDefinitions
|
|
2
|
-
import {
|
|
1
|
+
import { RuleRegistry, PolicyDefinitions } from '../audit-engine/index.js';
|
|
2
|
+
import { InventoryInitialisers, ShapeInitialisers } from './defaultClassifications.js';
|
|
3
3
|
import { DefaultPolicyDefinitions } from './defaultPolicies.js';
|
|
4
4
|
/**
|
|
5
5
|
* Exposes key functionality to load an audit config as static methods. This makes
|
|
@@ -13,20 +13,25 @@ export default class AuditConfig {
|
|
|
13
13
|
* @param con
|
|
14
14
|
*/
|
|
15
15
|
static async init(targetCon, opts) {
|
|
16
|
-
const conf = {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const defaultClassification = await classInitDef.initialiser(targetCon, opts?.preset);
|
|
20
|
-
if (defaultClassification) {
|
|
21
|
-
conf.classifications[className] = defaultClassification;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
16
|
+
const conf = { shape: {}, inventory: {}, policies: {}, acceptedRisks: {}, controls: {} };
|
|
17
|
+
conf.shape = await this.initSubtype(ShapeInitialisers, targetCon, opts);
|
|
18
|
+
conf.inventory = await this.initSubtype(InventoryInitialisers, targetCon, opts);
|
|
24
19
|
for (const policyName of Object.keys(PolicyDefinitions)) {
|
|
25
20
|
const policy = initPolicyConfig(policyName);
|
|
26
21
|
conf.policies[policyName] = policy;
|
|
27
22
|
}
|
|
28
23
|
return conf;
|
|
29
24
|
}
|
|
25
|
+
static async initSubtype(initialisable, targetCon, opts) {
|
|
26
|
+
const initPromises = Object.entries(initialisable).map(([, init]) => init(targetCon, opts?.preset));
|
|
27
|
+
const inits = await Promise.all(initPromises);
|
|
28
|
+
const result = {};
|
|
29
|
+
const keys = Object.keys(initialisable);
|
|
30
|
+
for (const initEntry of keys) {
|
|
31
|
+
result[initEntry] = inits.at(keys.indexOf(initEntry));
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
30
35
|
}
|
|
31
36
|
export function initPolicyConfig(policyName) {
|
|
32
37
|
const def = PolicyDefinitions[policyName];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auditConfig.js","sourceRoot":"","sources":["../../../src/libs/conf-init/auditConfig.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"auditConfig.js","sourceRoot":"","sources":["../../../src/libs/conf-init/auditConfig.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,YAAY,EAA0B,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAEnH,OAAO,EAAe,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACpG,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAYhE;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IAC9B;;;;;OAKG;IACI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAqB,EAAE,IAAuB;QACrE,MAAM,IAAI,GAAmB,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QACzG,IAAI,CAAC,KAAK,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,iBAAiB,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QACxE,IAAI,CAAC,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,qBAAqB,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QAChF,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACxD,MAAM,MAAM,GAAG,gBAAgB,CAAC,UAAsB,CAAC,CAAC;YACxD,IAAI,CAAC,QAAQ,CAAC,UAAsB,CAAC,GAAG,MAAa,CAAC;QACxD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,WAAW,CAC9B,aAA0C,EAC1C,SAAqB,EACrB,IAAuB;QAEvB,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QACpG,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC9C,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACxC,KAAK,MAAM,SAAS,IAAI,IAAI,EAAE,CAAC;YAC7B,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED,MAAM,UAAU,gBAAgB,CAAqB,UAAa;IAChE,MAAM,GAAG,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAC3D,KAAK,MAAM,SAAS,IAAI,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC;QACnD,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG;YACzB,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IACD,IAAI,wBAAwB,CAAC,UAAU,CAAC,EAAE,CAAC;QACzC,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,wBAAwB,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;IACnE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { Connection } from '@salesforce/core';
|
|
2
|
-
import {
|
|
2
|
+
import { Inventories, Shapes } from '../audit-engine/registry/definitions.js';
|
|
3
3
|
import { AuditInitPresets } from './init.types.js';
|
|
4
|
-
type
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export declare const ClassificationInitDefinitions: Record<Classifications, ClassificationDefinition>;
|
|
8
|
-
export {};
|
|
4
|
+
export type Initialiser = (con: Connection, preset?: AuditInitPresets) => Promise<unknown>;
|
|
5
|
+
export declare const ShapeInitialisers: Record<Shapes, Initialiser>;
|
|
6
|
+
export declare const InventoryInitialisers: Record<Inventories, Initialiser>;
|
|
@@ -1,22 +1,14 @@
|
|
|
1
1
|
import { PermissionRiskLevel, UserPrivilegeLevel } from '../audit-engine/index.js';
|
|
2
2
|
import { OrgDescribe, PermissionSets, Profiles, Users } from '../../salesforce/index.js';
|
|
3
3
|
import { loadPreset } from './presets.js';
|
|
4
|
-
export const
|
|
5
|
-
userPermissions:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
initialiser: initProfiles,
|
|
13
|
-
},
|
|
14
|
-
permissionSets: {
|
|
15
|
-
initialiser: initPermissionSets,
|
|
16
|
-
},
|
|
17
|
-
users: {
|
|
18
|
-
initialiser: initUsers,
|
|
19
|
-
},
|
|
4
|
+
export const ShapeInitialisers = {
|
|
5
|
+
userPermissions: initUserPermissions,
|
|
6
|
+
customPermissions: initCustomPermissions,
|
|
7
|
+
};
|
|
8
|
+
export const InventoryInitialisers = {
|
|
9
|
+
profiles: initProfiles,
|
|
10
|
+
permissionSets: initPermissionSets,
|
|
11
|
+
users: initUsers,
|
|
20
12
|
};
|
|
21
13
|
async function initUserPermissions(con, preset) {
|
|
22
14
|
const orgManager = await OrgDescribe.create(con);
|
|
@@ -24,8 +16,8 @@ async function initUserPermissions(con, preset) {
|
|
|
24
16
|
const presConfig = loadPreset(preset);
|
|
25
17
|
const perms = presConfig.classifyUserPermissions(userPerms);
|
|
26
18
|
perms.sort(classificationSorter);
|
|
27
|
-
const result = {
|
|
28
|
-
perms.forEach((perm) => (result
|
|
19
|
+
const result = {};
|
|
20
|
+
perms.forEach((perm) => (result[perm.name] = {
|
|
29
21
|
label: perm.label,
|
|
30
22
|
classification: perm.classification,
|
|
31
23
|
reason: perm.reason,
|
|
@@ -33,7 +25,7 @@ async function initUserPermissions(con, preset) {
|
|
|
33
25
|
return result;
|
|
34
26
|
}
|
|
35
27
|
async function initCustomPermissions(con) {
|
|
36
|
-
const result = {
|
|
28
|
+
const result = {};
|
|
37
29
|
const orgManager = await OrgDescribe.create(con);
|
|
38
30
|
const customPerms = orgManager.getCustomPermissions();
|
|
39
31
|
if (customPerms.length === 0) {
|
|
@@ -43,7 +35,7 @@ async function initCustomPermissions(con) {
|
|
|
43
35
|
...cp,
|
|
44
36
|
classification: PermissionRiskLevel.UNKNOWN,
|
|
45
37
|
}));
|
|
46
|
-
perms.forEach((perm) => (result
|
|
38
|
+
perms.forEach((perm) => (result[perm.name] = {
|
|
47
39
|
label: perm.label,
|
|
48
40
|
classification: perm.classification,
|
|
49
41
|
}));
|
|
@@ -52,29 +44,27 @@ async function initCustomPermissions(con) {
|
|
|
52
44
|
async function initProfiles(targetOrgCon) {
|
|
53
45
|
const profilesRepo = new Profiles(targetOrgCon);
|
|
54
46
|
const profiles = await profilesRepo.resolve();
|
|
55
|
-
const content = {
|
|
47
|
+
const content = {};
|
|
56
48
|
for (const profileName of profiles.keys()) {
|
|
57
|
-
content
|
|
49
|
+
content[profileName] = { role: UserPrivilegeLevel.UNKNOWN };
|
|
58
50
|
}
|
|
59
51
|
return content;
|
|
60
52
|
}
|
|
61
53
|
async function initPermissionSets(targetOrgCon) {
|
|
62
54
|
const permsetsRepo = new PermissionSets(targetOrgCon);
|
|
63
55
|
const permsets = await permsetsRepo.resolve({ isCustomOnly: true });
|
|
64
|
-
const content = {
|
|
56
|
+
const content = {};
|
|
65
57
|
for (const permsetName of permsets.keys()) {
|
|
66
|
-
content
|
|
58
|
+
content[permsetName] = { role: UserPrivilegeLevel.UNKNOWN };
|
|
67
59
|
}
|
|
68
60
|
return content;
|
|
69
61
|
}
|
|
70
62
|
async function initUsers(targetOrgCon) {
|
|
71
63
|
const usersRepo = new Users(targetOrgCon);
|
|
72
64
|
const users = await usersRepo.resolve();
|
|
73
|
-
const content = {
|
|
74
|
-
users: {},
|
|
75
|
-
};
|
|
65
|
+
const content = {};
|
|
76
66
|
for (const username of users.keys())
|
|
77
|
-
content
|
|
67
|
+
content[username] = { role: UserPrivilegeLevel.STANDARD_USER };
|
|
78
68
|
return content;
|
|
79
69
|
}
|
|
80
70
|
function resolveRiskLevelOrdinalValue(value) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultClassifications.js","sourceRoot":"","sources":["../../../src/libs/conf-init/defaultClassifications.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"defaultClassifications.js","sourceRoot":"","sources":["../../../src/libs/conf-init/defaultClassifications.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import z from 'zod';
|
|
2
2
|
import { AuditConfigShape } from '../audit-engine/index.js';
|
|
3
|
-
type
|
|
4
|
-
|
|
5
|
-
export type
|
|
3
|
+
type Shapes = (typeof AuditConfigShape)['shape']['files'];
|
|
4
|
+
type Inventories = (typeof AuditConfigShape)['inventory']['files'];
|
|
5
|
+
export type PermissionClassifications = z.infer<Shapes['userPermissions']['schema']>;
|
|
6
|
+
export type NamedPermissionClassification = PermissionClassifications['string'] & {
|
|
6
7
|
name: string;
|
|
7
8
|
};
|
|
8
9
|
export type UnclassifiedPerm = Omit<NamedPermissionClassification, 'classification'>;
|
|
9
|
-
export type ProfileClassifications = z.infer<
|
|
10
|
-
export type PermsetClassifications = z.infer<
|
|
11
|
-
export type UserClassifications = z.infer<
|
|
10
|
+
export type ProfileClassifications = z.infer<Inventories['profiles']['schema']>;
|
|
11
|
+
export type PermsetClassifications = z.infer<Inventories['permissionSets']['schema']>;
|
|
12
|
+
export type UserClassifications = z.infer<Inventories['users']['schema']>;
|
|
12
13
|
export declare enum AuditInitPresets {
|
|
13
14
|
strict = "strict",
|
|
14
15
|
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":"AAaA,MAAM,CAAN,IAAY,gBAIX;AAJD,WAAY,gBAAgB;IAC1B,qCAAiB,CAAA;IACjB,mCAAe,CAAA;IACf,iCAAa,CAAA;AACf,CAAC,EAJW,gBAAgB,KAAhB,gBAAgB,QAI3B"}
|
|
@@ -64,6 +64,10 @@ The "Permission Sets" policy requires at least userPermissions to be initialised
|
|
|
64
64
|
|
|
65
65
|
The "Profiles" policy requires a corresponding classification to be initialised.
|
|
66
66
|
|
|
67
|
+
# error.DirectoryDoesNotExistOrIsEmpty
|
|
68
|
+
|
|
69
|
+
%s does not exist or the directory is empty.
|
|
70
|
+
|
|
67
71
|
# error.InvalidConfigFileSchema
|
|
68
72
|
|
|
69
73
|
Failed to parse %s: %s.
|
|
@@ -6,6 +6,10 @@ Duplicate role identifier after normalization found: %s was already defined, %s
|
|
|
6
6
|
|
|
7
7
|
Tried to access a role that does not exist: %s.
|
|
8
8
|
|
|
9
|
+
# RoleReferencesPermissionThatDoesNotExist
|
|
10
|
+
|
|
11
|
+
Role %s references permission control %s that does not exist.
|
|
12
|
+
|
|
9
13
|
# violations.classification-preset-mismatch
|
|
10
14
|
|
|
11
15
|
Permission is classified as "%s" and not allowed in role "%s".
|
|
@@ -22,14 +26,6 @@ Permission classified as UNKNOWN. Update classification to LOW or higher to reso
|
|
|
22
26
|
|
|
23
27
|
Permission is assigned, but was not found in classification. Refresh or add manually.
|
|
24
28
|
|
|
25
|
-
# warnings.permission-not-classified-in-profile
|
|
26
|
-
|
|
27
|
-
Profile assigns the permission, but it was not found in classification. Refresh or add manually.
|
|
28
|
-
|
|
29
|
-
# warnings.permission-not-classified-in-permission-set
|
|
30
|
-
|
|
31
|
-
PermissionSet assigns the permission, but it was not found in classification. Refresh or add manually.
|
|
32
|
-
|
|
33
29
|
# error.failed-to-resolve-role
|
|
34
30
|
|
|
35
31
|
The assigned role "%s" was not valid for this audit. Check your role definitions.
|
package/oclif.manifest.json
CHANGED
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.20.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/j-schreiber/js-sf-cli-security-audit"
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { Profile } from '@jsforce/jsforce-node/lib/api/metadata.js';
|
|
2
|
-
import { PolicyRuleViolation, RuleComponentMessage } from '../result.types.js';
|
|
3
|
-
import { AuditRunConfig } from '../definitions.js';
|
|
4
|
-
import { PermissionClassifications } from '../shape/schema.js';
|
|
5
|
-
export type ResolvedProfileLike = {
|
|
6
|
-
name: string;
|
|
7
|
-
role: string;
|
|
8
|
-
metadata: PartialProfileLike;
|
|
9
|
-
};
|
|
10
|
-
export type ScanResult = {
|
|
11
|
-
violations: PolicyRuleViolation[];
|
|
12
|
-
warnings: RuleComponentMessage[];
|
|
13
|
-
};
|
|
14
|
-
export type PartialProfileLike = Pick<Profile, 'userPermissions' | 'customPermissions'>;
|
|
15
|
-
type PermissionsListKey = keyof PartialProfileLike;
|
|
16
|
-
/**
|
|
17
|
-
* Moves the "name" from the classifications map to object prop
|
|
18
|
-
*/
|
|
19
|
-
type NamedPermissionClassification = PermissionClassifications['string'] & {
|
|
20
|
-
name: string;
|
|
21
|
-
};
|
|
22
|
-
/**
|
|
23
|
-
* Scan userPermissions and customPermissions of a profile or permission set and
|
|
24
|
-
* get a unified scan result with violations (risk level not allowed) and warnings
|
|
25
|
-
* (risk level not classified)
|
|
26
|
-
*
|
|
27
|
-
* @param profileLike
|
|
28
|
-
* @param auditRun
|
|
29
|
-
* @param rootIdentifier Optional root identifier for messages to prepend.
|
|
30
|
-
* @returns
|
|
31
|
-
*/
|
|
32
|
-
export declare function scanProfileLike(profileLike: ResolvedProfileLike, auditRun: AuditRunConfig, rootIdentifier?: string[]): ScanResult;
|
|
33
|
-
export declare function scanPermissions(profile: ResolvedProfileLike, permissionListName: PermissionsListKey, auditRun: AuditRunConfig, rootIdentifier?: string[]): ScanResult;
|
|
34
|
-
export declare function resolvePresetOrdinalValue(value: string): number;
|
|
35
|
-
export declare function permissionAllowedInPreset(permClassification: string, preset: string): boolean;
|
|
36
|
-
export declare const classificationSorter: (a: NamedPermissionClassification, b: NamedPermissionClassification) => number;
|
|
37
|
-
export {};
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { Messages } from '@salesforce/core';
|
|
2
|
-
import { PermissionRiskLevel, UserPrivilegeLevel } from '../shape/schema.js';
|
|
3
|
-
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
4
|
-
const messages = Messages.loadMessages('@j-schreiber/sf-cli-security-audit', 'rules.enforceClassificationPresets');
|
|
5
|
-
/**
|
|
6
|
-
* Scan userPermissions and customPermissions of a profile or permission set and
|
|
7
|
-
* get a unified scan result with violations (risk level not allowed) and warnings
|
|
8
|
-
* (risk level not classified)
|
|
9
|
-
*
|
|
10
|
-
* @param profileLike
|
|
11
|
-
* @param auditRun
|
|
12
|
-
* @param rootIdentifier Optional root identifier for messages to prepend.
|
|
13
|
-
* @returns
|
|
14
|
-
*/
|
|
15
|
-
export function scanProfileLike(profileLike, auditRun, rootIdentifier) {
|
|
16
|
-
if (!profileLike.metadata) {
|
|
17
|
-
return { violations: [], warnings: [] };
|
|
18
|
-
}
|
|
19
|
-
const userPermsResult = scanPermissions(profileLike, 'userPermissions', auditRun, rootIdentifier);
|
|
20
|
-
const customPermsResult = scanPermissions(profileLike, 'customPermissions', auditRun, rootIdentifier);
|
|
21
|
-
userPermsResult.violations.push(...customPermsResult.violations);
|
|
22
|
-
userPermsResult.warnings.push(...customPermsResult.warnings);
|
|
23
|
-
return userPermsResult;
|
|
24
|
-
}
|
|
25
|
-
export function scanPermissions(profile, permissionListName, auditRun, rootIdentifier) {
|
|
26
|
-
const result = { warnings: [], violations: [] };
|
|
27
|
-
for (const perm of profile.metadata[permissionListName]) {
|
|
28
|
-
const identifier = rootIdentifier ? [...rootIdentifier, profile.name, perm.name] : [profile.name, perm.name];
|
|
29
|
-
const permClassification = resolvePerm(perm.name, auditRun, permissionListName);
|
|
30
|
-
if (permClassification) {
|
|
31
|
-
if (permClassification.classification === PermissionRiskLevel.BLOCKED) {
|
|
32
|
-
result.violations.push({
|
|
33
|
-
identifier,
|
|
34
|
-
message: messages.getMessage('violations.permission-is-blocked'),
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
else if (!permissionAllowedInPreset(permClassification.classification, profile.role)) {
|
|
38
|
-
result.violations.push({
|
|
39
|
-
identifier,
|
|
40
|
-
message: messages.getMessage('violations.classification-preset-mismatch', [
|
|
41
|
-
permClassification.classification,
|
|
42
|
-
profile.role,
|
|
43
|
-
]),
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
else if (permClassification.classification === PermissionRiskLevel.UNKNOWN) {
|
|
47
|
-
result.warnings.push({
|
|
48
|
-
identifier,
|
|
49
|
-
message: messages.getMessage('warnings.permission-unknown'),
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
result.warnings.push({
|
|
55
|
-
identifier,
|
|
56
|
-
message: messages.getMessage('warnings.permission-not-classified'),
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return result;
|
|
61
|
-
}
|
|
62
|
-
export function resolvePresetOrdinalValue(value) {
|
|
63
|
-
return Object.keys(UserPrivilegeLevel).indexOf(value.toUpperCase().replace(' ', '_'));
|
|
64
|
-
}
|
|
65
|
-
export function permissionAllowedInPreset(permClassification, preset) {
|
|
66
|
-
// this works, as long as we are mindful when adding new risk levels and presets
|
|
67
|
-
const invertedPermValue = Object.keys(PermissionRiskLevel).length - resolveRiskLevelOrdinalValue(permClassification);
|
|
68
|
-
const invertedPresetValue = Object.keys(UserPrivilegeLevel).length - resolvePresetOrdinalValue(preset);
|
|
69
|
-
return invertedPresetValue >= invertedPermValue;
|
|
70
|
-
}
|
|
71
|
-
function resolveRiskLevelOrdinalValue(value) {
|
|
72
|
-
return Object.keys(PermissionRiskLevel).indexOf(value.toUpperCase());
|
|
73
|
-
}
|
|
74
|
-
export const classificationSorter = (a, b) => resolveRiskLevelOrdinalValue(a.classification) - resolveRiskLevelOrdinalValue(b.classification);
|
|
75
|
-
function resolvePerm(permName, auditRun, type) {
|
|
76
|
-
return nameClassification(permName, auditRun.classifications[type]?.permissions[permName]);
|
|
77
|
-
}
|
|
78
|
-
function nameClassification(permName, perm) {
|
|
79
|
-
return perm ? { name: permName, ...perm } : undefined;
|
|
80
|
-
}
|
|
81
|
-
//# sourceMappingURL=permissionsScanning.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"permissionsScanning.js","sourceRoot":"","sources":["../../../../../src/libs/audit-engine/registry/helpers/permissionsScanning.ts"],"names":[],"mappings":"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"}
|