Skip to content

Commit

Permalink
Merge pull request #110 from Lightning-Flow-Scanner/feature/unsafe-ru…
Browse files Browse the repository at this point in the history
…nning-context

feat: new rule unsafe running context
  • Loading branch information
junners authored Jul 25, 2024
2 parents 932aa81 + 1053746 commit 41388f8
Show file tree
Hide file tree
Showing 12 changed files with 393 additions and 149 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ src/main/.DS_Store
dist/
out/

.nyc_output/
.nyc_output/

.DS_Store
274 changes: 138 additions & 136 deletions package-lock.json

Large diffs are not rendered by default.

17 changes: 10 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
"precommit": "lint-staged",
"lint": "eslint src",
"prepack": "npm run build && npm run dist",
"dist": "rollup --config",
"rollup": "rollup --config",
"uglify": "uglifyjs dist/index.js --compress -o dist/index.min.js",
"dist": "npm run rollup && npm run uglify",
"test:coverage": "nyc npm test"
},
"keywords": [],
Expand All @@ -29,22 +31,23 @@
"@rollup/plugin-typescript": "^11.1.6",
"@types/chai": "^4.3.16",
"@types/mocha": "^10.0.7",
"@types/node": "^20.14.10",
"@types/node": "^20.14.12",
"chai": "4.4.1",
"eslint": "8.57.0",
"husky": "^9.0.11",
"husky": "^9.1.1",
"lint-staged": "^15.2.7",
"logging": "^3.3.0",
"mocha": "^10.6.0",
"mocha": "^10.7.0",
"nyc": "^17.0.0",
"prettier": "^3.3.3",
"rollup": "^4.18.1",
"rollup": "^4.19.0",
"rollup-plugin-polyfill-node": "^0.13.0",
"semantic-release": "^24.0.0",
"ts-node": "^10.9.2",
"tslib": "^2.6.3",
"typescript": "^5.5.3",
"typescript-eslint": "^7.16.0"
"typescript": "^5.5.4",
"typescript-eslint": "^7.17.0",
"uglify-js": "^3.19.0"
},
"packageManager": "[email protected]",
"dependencies": {
Expand Down
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ _An Extensible Rule Engine capable of conducting static analysis on the metadata
| **SOQL Query In A Loop** ([`SOQLQueryInLoop`](https://github.com/Lightning-Flow-Scanner/lightning-flow-scanner-core/tree/master/src/main/rules/SOQLQueryInLoop.ts)) | To prevent exceeding Apex governor limits, it is advisable to consolidate all your SOQL queries at the conclusion of the flow. |
| **Unconnected Element** ([`UnconnectedElement`](https://github.com/Lightning-Flow-Scanner/lightning-flow-scanner-core/tree/master/src/main/rules/UnconnectedElement.ts)) | Unconnected elements which are not being used by the Flow should be avoided to keep Flows efficient and maintainable. |
| **Unused Variable** ([`UnusedVariable`](https://github.com/Lightning-Flow-Scanner/lightning-flow-scanner-core/tree/master/src/main/rules/UnusedVariable.ts)) | To maintain the efficiency and manageability of your Flow, it's advisable to avoid including unconnected variables that are not in use. |
| **Unsafe Running Context** ([`UnsafeRunningContext`](https://github.com/Lightning-Flow-Scanner/lightning-flow-scanner-core/tree/master/src/main/rules/UnsafeRunningContext.ts)) | This flow is configured to run in System Mode without Sharing. This system context grants all running users the permission to view and edit all data in your org. Running a flow in System Mode without Sharing can lead to unsafe data access. |

## Core Functions

Expand Down
6 changes: 3 additions & 3 deletions rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ export default {
dir: "dist",
format: "umd",
name: "lightningflowscanner",
sourcemap: true,
sourcemap: false,
globals: {
"path-browserify": "p",
xmlbuilder2: "xmlbuilder2",
},
}
},
],
plugins: [
nodePolyfills(),
typescript({tsconfig: `tsconfig.umd.json`}),
typescript({ tsconfig: `tsconfig.umd.json` }),
nodeResolve({ preferBuiltins: true }),
nodePolyfills(),
],
Expand Down
41 changes: 41 additions & 0 deletions src/main/rules/UnsafeRunningContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import * as core from "../internals/internals";
import { RuleCommon } from "../models/RuleCommon";

export class UnsafeRunningContext extends RuleCommon implements core.IRuleDefinition {
constructor() {
super(
{
name: "UnsafeRunningContext",
label: "Unsafe Flow Running Context",
description:
"This flow is configured to run in System Mode without Sharing. This system context grants all running users the permission to view and edit all data in your org. Running a flow in System Mode without Sharing can lead to unsafe data access.",
supportedTypes: [...core.FlowType.backEndTypes, ...core.FlowType.visualTypes],
docRefs: [
{
label:
"Learn about data safety when running flows in system context in Salesforce Help",
path: "https://help.salesforce.com/s/articleView?id=sf.flow_distribute_context_data_safety_system_context.htm&type=5",
},
],
isConfigurable: false,
autoFixable: false,
},
{ severity: "warning" }
);
}

public execute(flow: core.Flow): core.RuleResult {
const hasRunInMode = "runInMode" in flow.xmldata;
const runInMode: string = hasRunInMode ? flow.xmldata.runInMode : undefined;
const riskyMode: string = "SystemModeWithoutSharing";

const results: core.ResultDetails[] = [];

if (hasRunInMode && runInMode === riskyMode) {
results.push(
new core.ResultDetails(new core.FlowAttribute(runInMode, "runInMode", `== ${riskyMode}`))
);
}
return new core.RuleResult(this, results);
}
}
4 changes: 3 additions & 1 deletion src/main/store/DefaultRuleStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import { MissingNullHandler } from "../rules/MissingNullHandler";
import { ProcessBuilder } from "../rules/ProcessBuilder";
import { SOQLQueryInLoop } from "../rules/SOQLQueryInLoop";
import { UnconnectedElement } from "../rules/UnconnectedElement";
import { UnsafeRunningContext } from "../rules/UnsafeRunningContext";
import { UnusedVariable } from "../rules/UnusedVariable";

export const DefaultRuleStore: {} = {
export const DefaultRuleStore: object = {
APIVersion,
AutoLayout,
CopyAPIName,
Expand All @@ -30,4 +31,5 @@ export const DefaultRuleStore: {} = {
UnconnectedElement,
UnusedVariable,
InactiveFlow,
UnsafeRunningContext,
};
47 changes: 47 additions & 0 deletions tests/UnsafeRunningContext.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { expect } from "chai";
import "mocha";
import * as core from "../src";
import * as path from "path-browserify";

import { ParseFlows } from "../src/main/libs/ParseFlows";
import { ParsedFlow } from "../src/main/models/ParsedFlow";

import { UnsafeRunningContext } from "../src/main/rules/UnsafeRunningContext";

describe("UnsafeRunningContext", () => {
const unsafeRunningContext: UnsafeRunningContext = new UnsafeRunningContext();

it("should have a scan result for without sharing system mode", async () => {
const unsafeContextTestFile = path.join(
__dirname,
"./xmlfiles/Unsafe_Running_Context.flow-meta.xml"
);
const parsed: ParsedFlow = (await ParseFlows([unsafeContextTestFile])).pop() as ParsedFlow;
const ruleResult: core.RuleResult = unsafeRunningContext.execute(parsed.flow as core.Flow);
expect(ruleResult.occurs).to.be.true;
expect(ruleResult.details).to.not.be.empty;
expect(ruleResult.ruleDefinition.severity).to.be.equal("warning");
});

it("should not have a scan result for with sharing system mode", async () => {
const unsafeContextTestFile = path.join(
__dirname,
"./xmlfiles/Unsafe_Running_Context_WithSharing.flow-meta.xml"
);
const parsed: ParsedFlow = (await ParseFlows([unsafeContextTestFile])).pop() as ParsedFlow;
const ruleResult: core.RuleResult = unsafeRunningContext.execute(parsed.flow as core.Flow);
expect(ruleResult.occurs).to.be.false;
expect(ruleResult.details).to.be.empty;
});

it("should not have a scan result for default mode", async () => {
const unsafeContextTestFile = path.join(
__dirname,
"./xmlfiles/Unsafe_Running_Context_Default.flow-meta.xml"
);
const parsed: ParsedFlow = (await ParseFlows([unsafeContextTestFile])).pop() as ParsedFlow;
const ruleResult: core.RuleResult = unsafeRunningContext.execute(parsed.flow as core.Flow);
expect(ruleResult.occurs).to.be.false;
expect(ruleResult.details).to.be.empty;
});
});
46 changes: 46 additions & 0 deletions tests/xmlfiles/Unsafe_Running_Context.flow-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<Flow xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>61.0</apiVersion>
<environments>Default</environments>
<interviewLabel>test {!$Flow.CurrentDateTime}</interviewLabel>
<label>test</label>
<processMetadataValues>
<name>BuilderType</name>
<value>
<stringValue>LightningFlowBuilder</stringValue>
</value>
</processMetadataValues>
<processMetadataValues>
<name>CanvasMode</name>
<value>
<stringValue>AUTO_LAYOUT_CANVAS</stringValue>
</value>
</processMetadataValues>
<processMetadataValues>
<name>OriginBuilderType</name>
<value>
<stringValue>LightningFlowBuilder</stringValue>
</value>
</processMetadataValues>
<processType>Flow</processType>
<runInMode>SystemModeWithoutSharing</runInMode>
<screens>
<name>testtest</name>
<label>test</label>
<locationX>176</locationX>
<locationY>134</locationY>
<allowBack>true</allowBack>
<allowFinish>true</allowFinish>
<allowPause>true</allowPause>
<showFooter>true</showFooter>
<showHeader>true</showHeader>
</screens>
<start>
<locationX>50</locationX>
<locationY>0</locationY>
<connector>
<targetReference>testtest</targetReference>
</connector>
</start>
<status>Draft</status>
</Flow>
50 changes: 50 additions & 0 deletions tests/xmlfiles/Unsafe_Running_Context_Default.flow-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<Flow xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>61.0</apiVersion>
<environments>Default</environments>
<interviewLabel>Unsafe Running Context {!$Flow.CurrentDateTime}</interviewLabel>
<label>Unsafe Running Context</label>
<processMetadataValues>
<name>BuilderType</name>
<value>
<stringValue>LightningFlowBuilder</stringValue>
</value>
</processMetadataValues>
<processMetadataValues>
<name>CanvasMode</name>
<value>
<stringValue>AUTO_LAYOUT_CANVAS</stringValue>
</value>
</processMetadataValues>
<processMetadataValues>
<name>OriginBuilderType</name>
<value>
<stringValue>LightningFlowBuilder</stringValue>
</value>
</processMetadataValues>
<processType>AutoLaunchedFlow</processType>
<recordCreates>
<description>asdfasdfasdfasdfasdf</description>
<name>Create_Record</name>
<label>Create Record</label>
<locationX>176</locationX>
<locationY>134</locationY>
<inputAssignments>
<field>LastName</field>
<value>
<stringValue>123</stringValue>
</value>
</inputAssignments>
<object>Contact</object>
<storeOutputAutomatically>true</storeOutputAutomatically>
</recordCreates>
<runInMode>DefaultMode</runInMode>
<start>
<locationX>50</locationX>
<locationY>0</locationY>
<connector>
<targetReference>Create_Record</targetReference>
</connector>
</start>
<status>Active</status>
</Flow>
50 changes: 50 additions & 0 deletions tests/xmlfiles/Unsafe_Running_Context_WithSharing.flow-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<Flow xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>61.0</apiVersion>
<environments>Default</environments>
<interviewLabel>Unsafe Running Context {!$Flow.CurrentDateTime}</interviewLabel>
<label>Unsafe Running Context</label>
<processMetadataValues>
<name>BuilderType</name>
<value>
<stringValue>LightningFlowBuilder</stringValue>
</value>
</processMetadataValues>
<processMetadataValues>
<name>CanvasMode</name>
<value>
<stringValue>AUTO_LAYOUT_CANVAS</stringValue>
</value>
</processMetadataValues>
<processMetadataValues>
<name>OriginBuilderType</name>
<value>
<stringValue>LightningFlowBuilder</stringValue>
</value>
</processMetadataValues>
<processType>AutoLaunchedFlow</processType>
<recordCreates>
<description>asdfasdfasdfasdfasdf</description>
<name>Create_Record</name>
<label>Create Record</label>
<locationX>176</locationX>
<locationY>134</locationY>
<inputAssignments>
<field>LastName</field>
<value>
<stringValue>123</stringValue>
</value>
</inputAssignments>
<object>Contact</object>
<storeOutputAutomatically>true</storeOutputAutomatically>
</recordCreates>
<runInMode>SystemModeWitSharing</runInMode>
<start>
<locationX>50</locationX>
<locationY>0</locationY>
<connector>
<targetReference>Create_Record</targetReference>
</connector>
</start>
<status>Active</status>
</Flow>
2 changes: 1 addition & 1 deletion tsconfig.umd.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"es6"
],
"experimentalDecorators": true,
"sourceMap": true,
"sourceMap": false,
"rootDir": "src",
"strict": false, /* enable all strict type-checking options */
"baseUrl": ".",
Expand Down

0 comments on commit 41388f8

Please sign in to comment.