/*
 * Copyright 2014-2017 ForgeRock AS. All Rights Reserved
 *
 * Use of this code requires a commercial software license with ForgeRock AS.
 * or with one of its affiliates. All use shall be exclusively subject
 * to such license between the licensee and ForgeRock AS.
 */

 -------------------------------------------------------------------------------------------------
                                    Salesforce Connector Sample
 -------------------------------------------------------------------------------------------------

 This sample will demonstrate a recon and sync between Salesforce and OrientDB. To get started you
 need access to a Salesforce account that has an app with OAuth enabled to allow us to retrieve a
 consumer key and a consumer secret. Salesforce uses OAuth 2.0. That app must have a callback url
 in the form,
    Protocol://hostname:portNumber/admin/oauth.html
 The "admin/oauth.html" is important to have so that OpenIDM can do that OAuth flow correctly.

 -------------------------------------------------------------------------------------------------
                      Getting the Consumer Key and Consumer Secret From Salesforce
 -------------------------------------------------------------------------------------------------

 From your Salesforce account you will need to have the following handy:
    1) Consumer Key
    2) Consumer Secret

 Your Salesforce account should have a few users in it to demonstrate reconciliation and sync.


 ------------------------------------------------------------------------------------------------------
                       Running the Salesforce Connector Sample via the Admin UI
 ------------------------------------------------------------------------------------------------------

 1) Start the Salesforce sample with the following command,

        ./startup.sh -p samples/salesforce-connector

 2) Go to the administration view in OpenIDM by going to the following URL:

        https://localhost:8443/admin

 3) You should now see the Salesforce connector icon with the connector disabled at this point. Use the
 Consumer Key and Consumer Secret that was retrieved in the section above to complete the OAuth 2.0 flow
 so that the connector can complete the activation process.
    a) Click on the Salesforce icon in the Connectors section to edit the connector
    b) In the section General Details, there is a drop down menu for Connector Type
        - use that drop down menu and select the Salesforce Connector
    c) Under the Base Connector Details, set the following items:
        1) Login URL : click the circle fill box to enable this as a Sandbox environment
        2) Enter in the Consumer Key in the Consumer Key input field.
        3) Enter in the Consumer Secret in the Consumer Secret input field.
        4) At the bottom of the page click Update.
        5) You will be asked by Salesforce to give consent to grants you set up in your app.

 After you have given consent to OpenIDM to retrieve users from your Salesforce account we can start
 a recon between Salesforce Users store and Managed Users.

 4) Select the Mappings tab on the OpenIDM UI to view the mappings that are available.
    -For this sample there are two mappings one from Salesforce Users to Managed Users and going back from
    Managed Users to Salesforce.

 5) Select the mapping that shows Salesforce as the source and Managed as the target.
 6) Click on the Reconcile Now button to perform the recon. If you click on the arrow on the left hand side by the
 completed sync message you will see details of the sync.
 7) To take a close look at the users that you brought in from Salesforce click on the User view button in the
 upper right hand side of the admin user view page.
 8) Click the Users tab from the navigation bar to view the users.

 Now that we are confident that we pulled in the users from Salesforce we want to test the mapping we created
 from Managed User to Salesforce User. We can do this by updating one of the users by selecting them while we
 are in the User view table.

 9) Select a user from the table, this will show the user profile attributes with values.
 10) For this sample we will just modify a first name of the entry we are looking at and click update.

 If you go back to your user view inside of Salesforce you will see that user now reflects the change you
 made through the OpenIDM UI console.


 ------------------------------------------------------------------------------------------------------
                       Running the Salesforce Connector Sample via the CLI
 ------------------------------------------------------------------------------------------------------

 1) Start the Salesforce sample with the following command,

        ./startup.sh -p samples/salesforce-connector

 Before you begin, you will need to get a refresh token from Salesforce

    Getting the refresh token:
    2) Open the following URL in a browser:
        https://test.salesforce.com/services/oauth2/authorize
        ?response_type=code&
        client_id=39pHRjzMVGOBdkd_TtUemBIrEgUEApjm26LlptbMwzqFHO2z5Urhxkz82JIeIfw1_LWdPMmv9mgK7iQMFhb7F&
        redirect_uri=https://localhost:8443/admin/oauth.html&
        scope=id%20api%20refresh_token

    3) At this point, you will be redirected to Salesforce to start the OAuth flow. You will be prompted
    to give this application access to your Salesforce account. After you have given consent, you will
    get an access token code for the next step.
        Copy the token from the response URL, the param is:

            code=aivXI2CLPrTMEmYhL5xJ8ib2Prx4OPchx_j4KaUZqKLk3AV064UQZByb4wB.xZviGxw6Pp5Et1%3D%3D

    4) With the code you retrieved in step 2, you will now retrieve a refresh token using the following
    request:
        curl -k -v https://test.salesforce.com/services/oauth2/token
        -d "grant_type=authorization_code"
        -d "client_id=39pHRjzMVGOBdkd_TtUemBIrEgUEApjm26LlptbMwzqFHO2z5Urhxkz82JIeIfw1_LWdPMmv9mgK7iQMFhb7F"
        -d "client_secret=4205519783546230274" -d "redirect_uri=https://localhost:8443/admin/oauth.html"
        -d "code=aivXI2CLPrTMEmYhL5xJ8ib2Prx4OPchx_j4KaUZqKLk3AV064UQZByb4wB.xZviGxw6Pp5Et1%3D%3D

        Response:
            {
                "id":"https://test.salesforce.com/id/{id}",
                "issued_at":"1416247254725",
                "scope":"id api refresh_token",
                instance_url":"https://test.salesforce.com",
                "token_type":"Bearer",
                "refresh_token":"5ASqK1VUUxep8tr93PeH6_gFfgjlM3QIo.dPFmaDYG43GrVTizDDQZKbxnJt2kvljmd5_Abjgq_ahOuJ9_jEWnaQ",
                "signature":"GENERATED_SIGNATURE",
                "access_token":"YOUR_ACCESS_TOKEN"
            }

    Now you have everything you need to edit the samples/salesforce/conf/provisioner.salesforce-salesforce.json
    configuration file. The Consumer Key, Consumer Secret, and refresh token.

    5) Open up the Salesforce provisioner config for editing.

            $ vi samples/salesforce-connector/conf/provisioner.salesforce-salesforce.json

        In the section "configurationProperties", use the response from step 3 to add the missing values

            "configurationProperties" : {
                    "connectTimeout" : 120000,
                    "loginUrl" : YOUR_LOGIN_URL,
                    "idleCheckInterval" : 10000,
                    "refreshToken" : "5ASqK1VUUxep8tr93PeH6_gFfgjlM3QIo.dPFmaDYG43GrVTizDDQZKbxnJt2kvljmd5_Abjgq_ahOuJ9_jEWnaQ",
                    "clientSecret" : "4205519783546230274",
                    "clientId" : "39pHRjzMVGOBdkd_TtUemBIrEgUEApjm26LlptbMwzqFHO2z5Urhxkz82JIeIfw1_LWdPMmv9mgK7iQMFhb7F",
                    "instanceUrl" : "https://test.salesforce.com",
                    "version" : 29
                }

        Make sure to enable the connector in this file.

            "enabled" : true

    After you save this file with your changes, the Salesforce connector should now be available.

    6) Test availability of Salesforce Connector

             $ curl -k  --header "X-OpenIDM-Username: openidm-admin"
                     --header "X-OpenIDM-Password: openidm-admin"
                     --header "Content-Type: application/json"
                     --request POST
                     "https://localhost:8443/openidm/system/salesforce?_action=test"

             Response should be:
             {
                 "name": "salesforce",
                 "enabled": true,
                 "config": "config/provisioner.salesforce/salesforce",
                 "objectTypes": [
                     "User",
                     "PermissionSet",
                     "PermissionSetAssignment",
                     "Profile",
                     "PermissionSetLicenseAssign",
                     "Organization",
                     "PermissionSetLicense",
                     "Group",
                     "GroupMember"
                 ],
                 "connectorRef": {
                     "connectorName": "org.forgerock.openidm.salesforce.Salesforce",
                     "bundleName": "org.forgerock.openidm.salesforce",
                     "displayName": "Salesforce Connector",
                     "systemType": "provisioner.salesforce",
                     "bundleVersion": "2.0.29.1-RC3-SNAPSHOT"
                 },
                 "ok": true
             }

   ------------------------------------------------------------------------------------------------------
                       Reconciling Salesforce Users to Managed Users via the CLI
   ------------------------------------------------------------------------------------------------------

   A sync.json is included with this sample which maps some user attributes from Salesforce to Managed User
   entries. To trigger a reconciliation with this mapping, simply issue the following command

      Request :
          $ curl -k  --header "X-OpenIDM-Username: openidm-admin"
                  --header "X-OpenIDM-Password: openidm-admin"
                  --header "Content-Type: application/json"
                  --request POST "https://localhost:8443/openidm/recon?_action=recon&mapping=sourceSalesforceUser_managedUser"

      Response :
              {"_id":"3d83b958-dfec-4675-8c49-68c568d0980b","state":"ACTIVE"}

    A quick look at the reconciliation entry will tell us what happened during the reconciliation process :

       Request :
           $ curl -k  --header "X-OpenIDM-Username: openidm-admin"
                   --header "X-OpenIDM-Password: openidm-admin"
                   --header "Content-Type: application/json"
                   --request GET "https://localhost:8443/openidm/recon/3d83b958-dfec-4675-8c49-68c568d0980b"
       Response:
             {
                "_id":"3d83b958-dfec-4675-8c49-68c568d0980b",
                "mapping":"sourceSalesforceUser_managedUser",
                "state":"SUCCESS",
                "stage":"COMPLETED_SUCCESS",
                "stageDescription":"reconciliation completed.",
                "progress":{
                   "source":{
                      "existing":{
                         "processed":5,
                         "total":"5"
                      }
                   },
                   "target":{
                      "existing":{
                         "processed":0,
                         "total":"0"
                      },
                      "created":5
                   },
                   "links":{
                      "existing":{
                         "processed":0,
                         "total":"0"
                      },
                      "created":5
                   }
                },
                "situationSummary":{
                   "SOURCE_IGNORED":0,
                   "MISSING":0,
                   "FOUND":0,
                   "AMBIGUOUS":0,
                   "UNQUALIFIED":0,
                   "CONFIRMED":0,
                   "SOURCE_MISSING":0,
                   "ABSENT":5,
                   "TARGET_IGNORED":0,
                   "UNASSIGNED":0,
                   "FOUND_ALREADY_LINKED":0
                },
                "statusSummary":{
                   "FAILURE":0,
                   "SUCCESS":5
                },
                "parameters":{
                   "object":{
                      "sourceQuery":{
                         "resourceName":"system/salesforce/User",
                         "_queryId":"query-all-ids"
                      },
                      "targetQuery":{
                         "resourceName":"managed/user",
                         "_queryId":"query-all-ids"
                      }
                   },
                   "pointer":{
                      "empty":true
                   },
                   "transformers":[

                   ],
                   "set":false,
                   "map":true,
                   "string":false,
                   "wrappedObject":{
                      "targetQuery":{
                         "_queryId":"query-all-ids",
                         "resourceName":"managed/user"
                      },
                      "sourceQuery":{
                         "_queryId":"query-all-ids",
                         "resourceName":"system/salesforce/User"
                      }
                   },
                   "list":false,
                   "number":false,
                   "boolean":false,
                   "null":false,
                   "collection":false
                },
                "started":"2014-11-17T20:19:07.201Z",
                "ended":"2014-11-17T20:19:08.676Z",
                "duration":1475
             }

This sample is just a starting place for using the Salesforce connector with OpenIDM.