Beispiel #1
0
        private static ConnectedApp ConstructConnectedApp(
            SalesforceConnectedServiceInstance salesforceInstance,
            Project project)
        {
            ConnectedApp connectedApp = new ConnectedApp();

            connectedApp.contactEmail = salesforceInstance.DesignTimeAuthentication.UserName;
            connectedApp.fullName     = salesforceInstance.ConnectedAppName;
            connectedApp.label        = salesforceInstance.ConnectedAppName;

            ConnectedAppOauthConfig oauthConfig = new ConnectedAppOauthConfig();

            connectedApp.oauthConfig = oauthConfig;
            oauthConfig.callbackUrl  = ConnectedAppHelper.GenerateAppCallbackUrl(salesforceInstance, project);
            oauthConfig.scopes       = new ConnectedAppOauthAccessScope[]
            {
                ConnectedAppOauthAccessScope.Api,
                ConnectedAppOauthAccessScope.Basic,
                ConnectedAppOauthAccessScope.RefreshToken,
            };

            string secret = Guid.NewGuid().ToString("N");

            salesforceInstance.RuntimeAuthentication.ConsumerSecret = secret;
            oauthConfig.consumerSecret = secret;

            return(connectedApp);
        }
Beispiel #2
0
        private static async Task CreateConnectedAppAsync(
            SalesforceConnectedServiceInstance salesforceInstance,
            MetadataService metadataService,
            ConnectedServiceLogger logger,
            Project project)
        {
            salesforceInstance.ConnectedAppName = ConnectedAppHelper.GetUniqueConnectedAppName(metadataService, project);
            ConnectedApp connectedApp = ConnectedAppHelper.ConstructConnectedApp(salesforceInstance, project);

            SaveResult[] saveResults = metadataService.createMetadata(new Metadata[] { connectedApp });

            if (ConnectedAppHelper.DoSaveResultsIndicateDuplicateValue(saveResults))
            {
                // The connected app failed to be created because one already exists with the specified name.  This implies that the
                // attempt to generate a unique name by reading the existing connected apps failed.  It is unknown at this point what
                // causes the Salesforce server to sometimes respond to a SOAP ReadMetadata request by returning nil for a Connected App
                // name that actually exists.  In this case, retry using a random number as the app name's suffix.

                Debug.Fail("A connected app named '{0}' already exists.  This implies that the Salesforce server responded to the SOAP ReadMetadata request to read this Connected App by returning nil for it even though it actually exists."
                           .FormatCurrentCulture(salesforceInstance.ConnectedAppName));

                string secondAttemptConnectedAppName = ConnectedAppHelper.GetUniqueConnectedAppName(metadataService, project, true);
                await logger.WriteMessageAsync(LoggerMessageCategory.Information, Resources.LogMessage_DuplicateConnectedAppName, salesforceInstance.ConnectedAppName, secondAttemptConnectedAppName);

                salesforceInstance.ConnectedAppName = secondAttemptConnectedAppName;
                connectedApp = ConnectedAppHelper.ConstructConnectedApp(salesforceInstance, project);
                saveResults  = metadataService.createMetadata(new Metadata[] { connectedApp });
            }

            if (saveResults.Length != 1 || !saveResults[0].success)
            {
                string errorMessages = saveResults.SelectMany(r => r.errors)
                                       .Select(e => e.message)
                                       .Aggregate((w, n) => w + "\r\n" + n);

                throw new InvalidOperationException(Resources.ConnectedAppHelper_FailedToCreateConnectedApp.FormatCurrentCulture(errorMessages));
            }
            else
            {
                ConnectedApp readConnectedApp = ConnectedAppHelper.GetConnectedAppByName(connectedApp.fullName, metadataService);
                if (readConnectedApp != null)
                {
                    salesforceInstance.RuntimeAuthentication.ConsumerKey = readConnectedApp.oauthConfig.consumerKey;
                }
                else
                {
                    await logger.WriteMessageAsync(LoggerMessageCategory.Warning, Resources.LogMessage_FailedReadingConnectedApp);

                    salesforceInstance.RuntimeAuthentication.ConsumerKey = Constants.ConfigValue_RequiredDefault;
                }
            }
        }
Beispiel #3
0
        public static async Task CreateConnectedAppAsync(
            SalesforceConnectedServiceInstance salesforceInstance,
            ConnectedServiceLogger logger,
            Project project)
        {
            using (MetadataService metadataService = new MetadataService())
            {
                metadataService.Url = salesforceInstance.DesignTimeAuthentication.MetadataServiceUrl;
                metadataService.SessionHeaderValue           = new SessionHeader();
                metadataService.SessionHeaderValue.sessionId = salesforceInstance.DesignTimeAuthentication.AccessToken;

                await AuthenticationHelper.ExecuteSalesforceRequestAsync <SoapHeaderException>(
                    salesforceInstance.DesignTimeAuthentication,
                    async() => await ConnectedAppHelper.CreateConnectedAppAsync(salesforceInstance, metadataService, logger, project),
                    (e) => e.Message.StartsWith("INVALID_SESSION_ID", StringComparison.OrdinalIgnoreCase),
                    () => metadataService.SessionHeaderValue.sessionId = salesforceInstance.DesignTimeAuthentication.AccessToken);
            }
        }
Beispiel #4
0
        private static string GetUniqueConnectedAppName(MetadataService metadataService, Project project, bool useRandomSuffix = false)
        {
            string validAppName = ConnectedAppHelper.MakeValidConnectedAppName(project.Name);

            string appNameSuffix;

            if (useRandomSuffix)
            {
                // The default Random constructor uses a seed value derived from the system clock and has finite resolution.  However,
                // because this code path is only hit once per running of the handler, this Random object having the same seed in subsequent
                // calls (and thus undesirably generating the same number) is not a concern.
                appNameSuffix = new Random().Next(100, 1000).ToString();
            }
            else
            {
                appNameSuffix = GeneralUtilities.GetUniqueSuffix(suffix =>
                                                                 ConnectedAppHelper.GetConnectedAppByName(validAppName + suffix, metadataService) != null);
            }

            return(validAppName + appNameSuffix);
        }