├── .forceignore
├── LICENSE
├── PlayByPlay-soapui-project.xml
├── README.md
├── config
└── project-scratch-def.json
├── enterprise_wsdl.xml
├── force-app
└── main
│ └── default
│ ├── applications
│ └── Play_by_Play.app-meta.xml
│ ├── aura
│ └── CalloutWidget
│ │ ├── CalloutWidget.cmp
│ │ ├── CalloutWidget.cmp-meta.xml
│ │ ├── CalloutWidgetController.js
│ │ └── CalloutWidgetHelper.js
│ ├── authproviders
│ ├── Custom.authprovider-meta.xml
│ └── DemoAuth.authprovider-meta.xml
│ ├── classes
│ ├── CustomAuthProvider.cls
│ ├── CustomAuthProvider.cls-meta.xml
│ ├── NamedCredentialInvoker.cls
│ └── NamedCredentialInvoker.cls-meta.xml
│ ├── customMetadata
│ └── Auth.Custom.md-meta.xml
│ ├── layouts
│ └── Auth__mdt-Auth Layout.layout-meta.xml
│ ├── namedCredentials
│ ├── Basic.namedCredential-meta.xml
│ ├── Custom.namedCredential-meta.xml
│ └── OAuth.namedCredential-meta.xml
│ ├── objects
│ └── Auth__mdt
│ │ ├── Auth__mdt.object-meta.xml
│ │ └── fields
│ │ ├── Client_Id__c.field-meta.xml
│ │ ├── Client_Secret__c.field-meta.xml
│ │ └── Token_Endpoint__c.field-meta.xml
│ ├── profiles
│ └── Demo.profile-meta.xml
│ └── tabs
│ └── Callout.tab-meta.xml
└── sfdx-project.json
/.forceignore:
--------------------------------------------------------------------------------
1 | # List files or directories below to ignore them when running force:source:push, force:source:pull, and force:source:status
2 | # More information: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_exclude_source.htm
3 | #
4 |
5 | package.xml
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 grekker
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Play by Play: Authenticating External App and Service Integrations with Salesforce #
2 | By Don Robins and Chuck Liddell
3 |
4 | https://www.pluralsight.com/courses/play-by-play-authenticating-external-app-service-integrations-salesforce
5 |
6 | ## What's In This Repo
7 |
8 | Companion code that was demonstrated during the video course. Code was created for demonstration purposes only and is provided here as-is with no warranty.
9 |
--------------------------------------------------------------------------------
/config/project-scratch-def.json:
--------------------------------------------------------------------------------
1 | {
2 | "orgName": "Alpha",
3 | "edition": "Developer",
4 | "orgPreferences" : {
5 | "enabled": ["S1DesktopEnabled"]
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/force-app/main/default/applications/Play_by_Play.app-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #0070D2
5 | false
6 |
7 | Large
8 |
9 | Standard
10 | standard-Account
11 | Callout
12 | Lightning
13 |
14 |
--------------------------------------------------------------------------------
/force-app/main/default/aura/CalloutWidget/CalloutWidget.cmp:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/force-app/main/default/aura/CalloutWidget/CalloutWidget.cmp-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 42.0
4 | CalloutWidget
5 |
6 |
--------------------------------------------------------------------------------
/force-app/main/default/aura/CalloutWidget/CalloutWidgetController.js:
--------------------------------------------------------------------------------
1 | ({
2 | /**
3 | * Called when the component is first loaded.
4 | */
5 | doInit : function(component, event, helper) {
6 |
7 | // call the server and fetch named credentials
8 | helper.getNamedCredentials(component);
9 | },
10 |
11 | /**
12 | * Send a message to the selected NamedCredential.
13 | */
14 | sendMessage : function(component, event, helper) {
15 |
16 | // call the server and pass it a message and a NamedCredential
17 | helper.sendMessage(component);
18 | }
19 | });
--------------------------------------------------------------------------------
/force-app/main/default/aura/CalloutWidget/CalloutWidgetHelper.js:
--------------------------------------------------------------------------------
1 | ({
2 | /**
3 | * Fetch a list of NamedCredential records from the server.
4 | */
5 | getNamedCredentials : function(component) {
6 |
7 | var action = component.get('c.serverGetNamedCredentials');
8 | action.setCallback(this, function(response){
9 | component.set('v.availableCredentials', response.getReturnValue());
10 | });
11 | $A.enqueueAction(action);
12 | },
13 |
14 | /**
15 | * Send a message to the endpoint for the selected NamedCredential.
16 | */
17 | sendMessage : function(component) {
18 |
19 | var action = component.get('c.serverSendMessage');
20 | action.setParams({
21 | 'selectedCredential' : component.get('v.selectedCredential'),
22 | 'message' : component.get('v.textToSend')
23 | });
24 | $A.enqueueAction(action);
25 | }
26 | });
--------------------------------------------------------------------------------
/force-app/main/default/authproviders/Custom.authprovider-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Auth__mdt.Custom
4 | test-qjrlpp2r3g73@example.com
5 | Custom
6 | false
7 | CustomAuthProvider
8 | Custom
9 | false
10 | false
11 |
12 |
--------------------------------------------------------------------------------
/force-app/main/default/authproviders/DemoAuth.authprovider-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | https://putsreq.com/DgpQxTzXAcEV0zfiKN0u
4 | thisIsMyKey
5 | gkzH3bNPuyd2aLpjlMxUUA==
6 | DemoAuth
7 | false
8 | OpenIdConnect
9 | true
10 | false
11 | https://putsreq.com/90UcOqafPS9yeytdmHN7
12 |
13 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/CustomAuthProvider.cls:
--------------------------------------------------------------------------------
1 | public with sharing class CustomAuthProvider extends Auth.AuthProviderPluginClass {
2 |
3 | private static String redirectUrl = 'https://fun-connect-1108-dev-ed.cs65.my.salesforce.com/services/authcallback/Custom';
4 |
5 | public String getCustomMetadataType() {
6 | return 'Auth__mdt';
7 | }
8 |
9 | public PageReference initiate(Map config, String stateToPropagate) {
10 | System.debug(LoggingLevel.WARN, 'initiate-config: ' + config);
11 | System.debug(LoggingLevel.WARN, 'initiate-stateToPropagate: ' + stateToPropagate);
12 | String url = config.get('Token_Endpoint__c');
13 | url += '?redirect_uri=' + redirectUrl + '&state=' + stateToPropagate;
14 | return new PageReference(url);
15 | }
16 |
17 | public Auth.AuthProviderTokenResponse handleCallback(Map config, Auth.AuthProviderCallbackState callbackState) {
18 | System.debug(LoggingLevel.WARN, 'handleCallback-config: ' + config);
19 | System.debug(LoggingLevel.WARN, 'handleCallback-callbackState: ' + callbackState);
20 | System.debug(LoggingLevel.WARN, 'handleCallback-token: ' + callbackState.queryParameters.get('token'));
21 | return new Auth.AuthProviderTokenResponse('PbP', callbackState.queryParameters.get('token'), null, callbackState.queryParameters.get('state'));
22 | }
23 |
24 | public Auth.UserData getUserInfo(Map config, Auth.AuthProviderTokenResponse response) {
25 | System.debug(LoggingLevel.WARN, 'getUserInfo-config: ' + config);
26 | System.debug(LoggingLevel.WARN, 'getUserInfo-response: ' + response);
27 | return new Auth.UserData('fakeId', 'first', 'last', 'full', 'email', 'link', null, null, null, null, null);
28 | }
29 |
30 | public override Auth.OAuthRefreshResult refresh(Map config, String refreshToken) {
31 | System.debug(LoggingLevel.WARN, 'refresh-config: ' + config);
32 | System.debug(LoggingLevel.WARN, 'refresh-refreshToken: ' + refreshToken);
33 | return null;
34 | }
35 | }
--------------------------------------------------------------------------------
/force-app/main/default/classes/CustomAuthProvider.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 42.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/NamedCredentialInvoker.cls:
--------------------------------------------------------------------------------
1 | /**
2 | * This class supports a Lightning component that allows the user to call arbitrary NamedCredential endpoints.
3 | */
4 | public with sharing class NamedCredentialInvoker {
5 |
6 | @AuraEnabled
7 | public static List