Skip to content

Commit

Permalink
Security enhancements (#188)
Browse files Browse the repository at this point in the history
* Added StripInaccessibleRecordFields__c setting

* Added all CMDT objects to LoggerAdmin.permissionset

* Added LogEntryDataMaskRule__mdt object for applying data mask rules to log entry message & record JSON fields in LogEntryEventBuilder

* Added CMDT rules for credit card numbers & social security numbers

* Added setting ApplyDataMaskRules__c to control if CMDT data mask rules are applied

* Added some user managament settings to scratch-def files

* Added test suites for each module

* Moved some test helper methods to LoggerTestUtils, cleaned up LogEntryEventBuilder_Tests methods

* Optimized setTagsDetails()

* Made record & records parameters optional in FlowRecordLogEntry & FlowCollectionLogEntry (respectively) to handle situations where null is passed (e.g., Get Records returns null for no matches, instead of an empty list) (reported in #198)

* Changed FlowDescription__c.field to long text area + added automatic field-truncation for LogEntry__c inserts + added a ridiculously long description to one of the Flows in nebula-logger-recipes (reported in #199)

* Made fancier buttons that include the release number

* Cleaned up a few areas in README

* Added 'Code Quality Tests' to deploy.yml + ran prettier

* Setup ESLint for lwc + fixed some reported issues

* Removed some unused scripts in package.json

* Switched back to using extra-tests folder, created LogEntryEventBuilder_IntegrationTests class (AccountBrand doesn't exist in all orgs)

* Added new step to pipeline to create an unvalidated package version & auto-install it into the package-demo org, then reinstall the latest released package version

* Reenabled Codecov.io integration in the pipeline

* Added static code analysis / PMD through sfdx-scanner (#201 by @jamessimone)

* Fixed line breaks not working when calling System.debug()
@jamessimone and I had a lot of... "fun" with this one

Co-authored-by: James Simone <[email protected]>
  • Loading branch information
jongpie and jamessimone authored Sep 14, 2021
1 parent 4938da6 commit 408580f
Show file tree
Hide file tree
Showing 157 changed files with 3,750 additions and 1,244 deletions.
26 changes: 26 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"parser": "@babel/eslint-parser",
"parserOptions": {
"requireConfigFile": false,
"babelOptions": {
"parserOpts": {
"plugins": ["classProperties", ["decorators", { "decoratorsBeforeExport": false }]]
}
}
},
"ignorePatterns": ["**/*.html", "**/*.cmp", "**/*.cmp-meta.xml", "**/*.css", "**/*.test.js", "**/*js-meta.xml", "**/*.json"],
"plugins": ["@lwc/eslint-plugin-lwc", "@salesforce/eslint-plugin-aura"],
"extends": ["@salesforce/eslint-config-lwc/recommended"],
"rules": {
"eqeqeq": "off",
"no-console": "off",
"no-unused-expressions": "off",
"semi": "off",
"@lwc/lwc/consistent-component-name": "error",
"@lwc/lwc/no-api-reassignments": "off",
"@lwc/lwc/no-async-operation": "off",
"@lwc/lwc/no-deprecated": "error",
"@lwc/lwc/no-document-query": "error",
"@lwc/lwc/valid-api": "error"
}
}
3 changes: 2 additions & 1 deletion .forceignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ nebula-logger/main/default/**

# Directory/package-specific README files
**/README.md
**/.content/**

# LWC configuration files
**/jsconfig.json
**/.eslintrc.json

# LWC Jest
**/__tests__/**
**/__tests__/**
141 changes: 92 additions & 49 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Unique name for this workflow
# Pipeline for Nebula Logger
name: Deployment

on:
Expand Down Expand Up @@ -39,12 +39,11 @@ on:
- 'sfdx-project.json'

jobs:
local-tests:
name: 'Local Tests'
code-quality-tests:
name: 'Code Quality Tests'
runs-on: ubuntu-latest
environment: Test
steps:
# Checkout the code
- name: 'Checkout source code'
uses: actions/checkout@v2

Expand All @@ -56,41 +55,55 @@ jobs:
- name: 'Install npm'
run: npm install

# Install Salesforce CLI
- name: 'Lint Lightning Components'
run: npm run lint:lwc

- name: 'Prettier code formatting verification'
run: npm run prettier:verify

- name: Install Salesforce CLI
run: npm install sfdx-cli --global
# run: |
# wget https://developer.salesforce.com/media/salesforce-cli/sfdx-linux-amd64.tar.xz
# mkdir sfdx-cli
# tar xJf sfdx-linux-amd64.tar.xz -C sfdx-cli --strip-components 1
# ./sfdx-cli/install

# Start local testing
# TODO uncomment
# Prettier formatting
# - name: 'Code formatting verification with Prettier'
# run: npm run prettier:verify
# TODO uncomment
# Lint LWC
# - name: 'Lint Lightning Web Components'
# run: npm run lint:lwc
# LWC unit tests

- name: Install & run SFDX Scanner
run: |
sfdx plugins:install @salesforce/sfdx-scanner
sfdx scanner:run --pmdconfig config/pmd-ruleset.xml --target . --engine pmd --severity-threshold 3
lwc-tests:
name: 'LWC Tests'
needs: [code-quality-tests]
runs-on: ubuntu-latest
environment: Test
steps:
- name: 'Checkout source code'
uses: actions/checkout@v2

- name: 'Setup node'
uses: actions/setup-node@v2
with:
node-version: '14'

- name: 'Install npm'
run: npm install

- name: Install Salesforce CLI
run: npm install sfdx-cli --global

- name: 'Run LWC Tests'
run: npm run test:lwc

# Upload code coverage data for LWC
# - name: 'Upload code coverage for LWC to Codecov.io'
# uses: codecov/[email protected]
# with:
# token: ${{ secrets.CODECOV_TOKEN }}
# flags: LWC
- name: 'Upload LWC code coverage to Codecov.io'
uses: codecov/[email protected]
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: LWC

scratch-org-tests:
name: 'Scratch Org Tests'
needs: [code-quality-tests]
runs-on: ubuntu-latest
environment: Test
steps:
# Checkout the code
- name: 'Checkout source code'
uses: actions/checkout@v2

Expand All @@ -102,18 +115,9 @@ jobs:
- name: 'Install npm'
run: npm install

# Install Salesforce CLI
- name: Install Salesforce CLI
run: npm install sfdx-cli --global
# run: |
# wget https://developer.salesforce.com/media/salesforce-cli/sfdx-linux-amd64.tar.xz
# mkdir sfdx-cli
# tar xJf sfdx-linux-amd64.tar.xz -C sfdx-cli --strip-components 1
# ./sfdx-cli/install

# Start remote testing

# Store secrets for dev hubs
- name: 'Populate DevHub Auth Files'
shell: bash
run: |
Expand Down Expand Up @@ -142,31 +146,70 @@ jobs:
with:
args: '120'

- name: 'Deploy Metadata'
run: npm run deploy
- name: 'Push Metadata'
run: sfdx force:source:push --forceoverwrite

- name: 'Run Apex Tests'
run: npm run test:apex

# Delete test files that Codecov is unable to parse
# - name: 'Delete unsupported code coverage files'
# run: rm ./tests/apex/test-result-707*-codecoverage.json
- name: 'Delete unsupported code coverage files'
run: rm ./tests/apex/test-result-707*-codecoverage.json

# Upload code coverage data for Apex
# - name: 'Upload code coverage for Apex to Codecov.io'
# uses: codecov/[email protected]
# with:
# token: ${{ secrets.CODECOV_TOKEN }}
# flags: Apex
- name: 'Upload Apex test code coverage to Codecov.io'
uses: codecov/[email protected]
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: Apex

- name: 'Delete Scratch Org'
run: npm run org:delete:noprompt
if: ${{ always() }}

create-and-install-test-package-version:
name: 'Create & Install Test Package Version'
needs: [lwc-tests, scratch-org-tests]
if: ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
environment: Test
steps:
- name: 'Checkout source code'
uses: actions/checkout@v2

- name: 'Setup node'
uses: actions/setup-node@v2
with:
node-version: '14'

- name: 'Install npm'
run: npm install

- name: Install Salesforce CLI
run: npm install sfdx-cli --global

- name: 'Populate Org Auth Files'
shell: bash
run: |
echo ${{ env.DEVHUB_SFDX_URL }} > ./DEVHUB_SFDX_URL.txt
echo ${{ env.NEBULA_PKG_DEMO_SANDBOX_SFDX_URL }} > ./NEBULA_PKG_DEMO_SANDBOX_SFDX_URL.txt
env:
DEVHUB_SFDX_URL: ${{ secrets.DEVHUB_SFDX_URL }}
NEBULA_PKG_DEMO_SANDBOX_SFDX_URL: ${{ secrets.NEBULA_PKG_DEMO_SANDBOX_SFDX_URL }}

- name: 'Authorize Orgs'
run: |
sfdx auth:sfdxurl:store --sfdxurlfile ./DEVHUB_SFDX_URL.txt --setalias nebula-logger-packaging --setdefaultdevhubusername
sfdx auth:sfdxurl:store --sfdxurlfile ./NEBULA_PKG_DEMO_SANDBOX_SFDX_URL.txt --setalias nebula-logger-package-demo
- name: 'Create & Install Unvalidated Package Version'
run: npx pwsh ./scripts/create-and-install-unvalidated-package-version.ps1 -targetusername nebula-logger-package-demo

- name: 'Reinstall Latest Released Package Version'
run: npx pwsh ./scripts/install-latest-released-unlocked-package-version.ps1 -targetusername nebula-logger-package-demo

# TODO finish auto-creation & promotion of unlocked package + committing changes to docs
# create-package-version:
# name: 'Create Package Version'
# needs: [local-tests, scratch-org-tests]
# needs: [code-quality-tests, lwc-tests, scratch-org-tests]
# runs-on: ubuntu-latest
# environment: Test
# steps:
Expand Down
7 changes: 1 addition & 6 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,12 @@
.settings/
.sfdx/
.vscode/
examples/
nebula-logger/main/default/
nebula-logger/managed-package/
packages/
scripts/
tests/

# NPM
node_modules/
package-lock.json
yarn.lock

# Files to exclude
*.log
*.log
26 changes: 11 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

Designed for Salesforce admins, developers & architects. A robust logger for Apex, Lightning Components, Flow, Process Builder & Integrations.

[![Install Unlocked Package](./content/btn-install-unlocked-package.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015khXQAQ)
[![Install Unlocked Package](./content/btn-install-unlocked-package.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015klZQAQ)
[![Install Managed Package](./content/btn-install-managed-package.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015keOQAQ)
[![View Documentation](./content/btn-view-documentation.png)](https://jongpie.github.io/NebulaLogger/)

Expand All @@ -18,18 +18,19 @@ Designed for Salesforce admins, developers & architects. A robust logger for Ape
3. Leverage `LogEntryEvent__e` platform events for real-time monitoring & integrations
4. Enable logging and set the logging level for different users & profiles using `LoggerSettings__c` custom hierarchy setting
- In addition to the required fields on this Custom Setting record, `LoggerSettings__c` ships with `SystemLogMessageFormat__c`, which uses Handlebars-esque syntax to refer to fields on the `LogEntryEvent__e` Platform Event. You can use curly braces to denote merge field logic, eg: `{OriginLocation__c}\n{Message__c}` - this will output the contents of `LogEntryEvent__e.OriginLocation__c`, a line break, and then the contents of `LogEntryEvent__e.Message__c`
5. View related log entries on any Lighting SObject flexipage by adding the 'Related Log Entries' component in App Builder
6. Dynamically assign tags to `Log__c` and `LogEntry__c` records for tagging/labeling your logs
7. Plugin framework: easily build or install plugins that enhance the `Log__c` and `LogEntry__c` objects, using Apex or Flow (not currently available in the managed package)
8. Event-Driven Integrations with [Platform Events](https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_intro.htm), an event-driven messaging architecture. External integrations can subscribe to log events using the `LogEntryEvent__e` object - see more details at [the Platform Events Developer Guide site](https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_subscribe_cometd.htm)
5. Automatically mask sensitive data by configuring `LogEntryDataMaskRule__mdt` custom metadata rules
6. View related log entries on any Lighting SObject flexipage by adding the 'Related Log Entries' component in App Builder
7. Dynamically assign tags to `Log__c` and `LogEntry__c` records for tagging/labeling your logs
8. Plugin framework: easily build or install plugins that enhance the `Log__c` and `LogEntry__c` objects, using Apex or Flow (not currently available in the managed package)
9. Event-Driven Integrations with [Platform Events](https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_intro.htm), an event-driven messaging architecture. External integrations can subscribe to log events using the `LogEntryEvent__e` object - see more details at [the Platform Events Developer Guide site](https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_subscribe_cometd.htm)

Learn more about the design and history of the project on [Joys Of Apex blog post](https://www.joysofapex.com/advanced-logging-using-nebula-logger/)

---

## Installing

You can choose to install the unlocked package, you can deploy the metadata from this repo to your org, or you can install the managed package. The metadata is the same in all 3 options, but there are some differences in using the 3 versions. All examples in README are for the unlocked package/unpackaged metadata (no namespace) - simply add the `Nebula` namespace from the examples if you are using the managed package.
Nebula Logger is available as both an unlocked package and a managed package. The metadata is the same in both packages, but there are some differences in the available functionality & features. All examples in `README` are for the unlocked package (no namespace) - simply add the `Nebula` namespace to the examples if you are using the managed package.

<table>
<thead>
Expand Down Expand Up @@ -57,22 +58,17 @@ You can choose to install the unlocked package, you can deploy the metadata from
</tr>
<tr>
<td>Apex Debug Statements</td>
<td><code>System.debug()</code> is automatically called - the output can be configured with LoggerSettings__c.SystemLogMessageFormat__c to use any field on LogEntryEvent__e</td>
<td><code>System.debug()</code> is automatically called - the output can be configured with <code>LoggerSettings__c.SystemLogMessageFormat__c</code> to use any field on <code>LogEntryEvent__e</code></td>
<td>Requires adding your own calls for <code>System.debug()</code> due to Salesforce limitations with managed packages</td>
</tr>
<tr>
<td>Apex Stack Traces</td>
<td>Automatically stored in <code>LogEntry__c.StackTrace__c</code> when calling methods like <code>Logger.debug('my message');</code></td>
<td>Requires calling <code>parseStackTrace()</code> due to Salesforce limitations with managed packages. For example:<br><code>Logger.debug('my message').parseStackTrace(new DmlException().getStackTrace());</code></td>
</tr>
<tr>
<td>Assign Topics (Tagging/Labeling System)</td>
<td>Provide <code>List&lt;String&gt; topics</code> in Apex or Flow to dynamically assign Salesforce Topics to <code>Log__c</code> and <code>LogEntry__c</code> records</td>
<td>This functionality is not currently available in the managed package</td>
</tr>
<tr>
<td>Logger Plugin Framework</td>
<td>Leverage Apex or Flow to build your own "plugins" for Logger - to add your own automation to the <code>Log__c</code> or <code>LogEntry__c</code> objects. The logger system will then automatically run your plugins after each trigger event (BEFORE_INSERT, BEFORE_UPDATE, AFTER_INSERT, AFTER_UPDATE, and so on).</td>
<td>Leverage Apex or Flow to build your own "plugins" for Logger - easily add your own automation to the any of the included objects: <code>LogEntryEvent__e</code>, <code>Log__c</code>, <code>LogEntry__c</code>, <code>LogEntryTag__c</code> and <code>LoggerTag__c</code>. The logger system will then automatically run your plugins for each trigger event (BEFORE_INSERT, BEFORE_UPDATE, AFTER_INSERT, AFTER_UPDATE, and so on).</td>
<td>This functionality is not currently available in the managed package</td>
</tr>
</tbody>
Expand All @@ -85,7 +81,7 @@ You can choose to install the unlocked package, you can deploy the metadata from
After deploying Nebula Logger to your org, there are a few additional configuration changes needed...

- Assign permission set(s) to users
- `LoggerLogCreator` provides the minimum access needed for users to generate logs via Apex, Flow or Process Builder
- `LoggerLogCreator` provides the minimum access needed for users to generate logs via Apex, Lightning Components, Flow or Process Builder
- `LoggerEndUser` provides access to generate logs, as well as read-only access to any log records shared with the user.
- `LoggerLogViewer` provides view-all access (read-only) to all log records. This does **not** provide access to generate logs.
- `LoggerAdmin` provides view-all and modify-all access to all log records.
Expand Down Expand Up @@ -336,7 +332,7 @@ Logger.debug('my string').setRecord(currentUser);
Logger.saveLog();
```

### Using LogMessage to Improve CPU Usage for String Formatting
### Using LogMessage for Dynamically-Generated Strings

The class `LogMessage` provides the ability to generate string messages on demand, using `String.format()`. This provides 2 benefits:

Expand Down
2 changes: 2 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ coverage:
threshold: 1%
if_ci_failed: success
patch: off
ignore:
- 'nebula-logger-recipes/**/*'
45 changes: 45 additions & 0 deletions config/pmd-ruleset.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" ?>
<ruleset
name="Nebula Logger Rules"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"
>
<description>
Nebula Logger custom PMD ruleset
</description>
<rule ref="category/apex/bestpractices.xml">
<exclude name="ApexAssertionsShouldIncludeMessage" />
<exclude name="AvoidGlobalModifier" />
<exclude name="AvoidLogicInTrigger" />
</rule>
<rule ref="category/apex/codestyle.xml">
<exclude name="FieldNamingConventions" />
<exclude name="MethodNamingConventions" />
<exclude name="PropertyNamingConventions" />
<exclude name="VariableNamingConventions" />
</rule>
<rule ref="category/apex/design.xml">
<exclude name="AvoidDeeplyNestedIfStmts" />
<exclude name="CognitiveComplexity" />
<exclude name="CyclomaticComplexity" />
<exclude name="ExcessiveClassLength" />
<exclude name="ExcessiveParameterList" />
<exclude name="ExcessivePublicCount" />
<exclude name="NcssConstructorCount" />
<exclude name="NcssMethodCount" />
<exclude name="StdCyclomaticComplexity" />
<exclude name="TooManyFields" />
</rule>
<rule ref="category/apex/documentation.xml">
<exclude name="ApexDoc" />
</rule>
<rule ref="category/apex/errorprone.xml">
<exclude name="EmptyStatementBlock" />
</rule>
<rule ref="category/apex/performance.xml">
<exclude name="AvoidDebugStatements" />
</rule>
<rule ref="category/apex/security.xml">
</rule>
</ruleset>
Loading

0 comments on commit 408580f

Please sign in to comment.