//------------ Destroy Data ------

        internal static DataAccessResponseType DestroySqlSchemaAndTables(Account account)
        {
            var response = new DataAccessResponseType();

            try
            {
                return(Sql.Statements.StoredProcedures.DestroySchema(account.SchemaName, account.SqlPartition));
            }
            catch (Exception e)
            {
                response.isSuccess    = false;
                response.ErrorMessage = e.Message;

                //Log exception and email platform admins
                PlatformExceptionsHelper.LogExceptionAndAlertAdmins(
                    e,
                    "attempting to destroy SQL schema and tables for : " + account.AccountName,
                    System.Reflection.MethodBase.GetCurrentMethod()
                    );

                PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Exception, "Error destroying schema for: '" + account.AccountName + "' on: ' " + account.SqlPartition + "'", "AccountID: '" + account.AccountID + "' AccountNameKey: '" + account.AccountNameKey + "' Error: '" + e.Message + "'", account.AccountID.ToString(), account.AccountName);
            }

            return(response);
        }
        /// <summary>
        /// Deletes a single image record from table storage
        /// </summary>
        /// <param name="accountId"></param>
        /// <param name="objectId"></param>
        /// <param name="imageGroupTypeNameKey"></param>
        /// <param name="imageGroupNameKey"></param>
        /// <param name="imageFormatNameKey"></param>
        /// <returns></returns>
        internal static DataAccessResponseType DeleteImageRecord(string accountId, string storagePartition, string imageFormatGroupTypeNameKey, string objectId, string imageGroupNameKey, string imageFormatNameKey)
        {
            var response = new DataAccessResponseType();

            var imageKey = imageGroupNameKey + "-" + imageFormatNameKey;

            //CloudTableClient cloudTableClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.AccountsStorage.CreateCloudTableClient();
            CloudTableClient cloudTableClient = Settings.Azure.Storage.GetStoragePartitionAccount(storagePartition).CreateCloudTableClient();

            //Create and set retry policy
            //IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(1), 4);
            IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 4);

            cloudTableClient.DefaultRequestOptions.RetryPolicy = linearRetryPolicy;



            try
            {
                //Delete from MAIN table
                CloudTable cloudTable1 = cloudTableClient.GetTableReference(Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(accountId) + ImageRecordTableName(imageFormatGroupTypeNameKey));
                //cloudTable1.CreateIfNotExists();
                TableEntity productImageEntity1 = cloudTable1.CreateQuery <TableEntity>().Where(p => p.PartitionKey == objectId && p.RowKey == imageKey).FirstOrDefault();
                cloudTable1.Execute(TableOperation.Delete(productImageEntity1));


                //Delete from LISTINGS table (We allow this to fail silently in case this is not a listing image
                try
                {
                    CloudTable cloudTable2 = cloudTableClient.GetTableReference(Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(accountId) + ImageRecordListingTableName(imageFormatGroupTypeNameKey));
                    //cloudTable2.CreateIfNotExists();
                    TableEntity productImageEntity2 = cloudTable2.CreateQuery <TableEntity>().Where(p => p.PartitionKey == objectId && p.RowKey == imageKey).FirstOrDefault();
                    cloudTable2.Execute(TableOperation.Delete(productImageEntity2));
                }
                catch
                {
                }

                response.isSuccess = true;
            }
            catch (Exception e)
            {
                PlatformLogManager.LogActivity(
                    CategoryType.Error,
                    ActivityType.Error_Exception,
                    e.Message,
                    "Exception while attempting to delete image record/rowKey'" + imageKey + "' for " + imageFormatGroupTypeNameKey + " '" + objectId + "' in table storage",
                    accountId,
                    null,
                    null,
                    null,
                    null,
                    null,
                    System.Reflection.MethodBase.GetCurrentMethod().ToString(),
                    null
                    );
            }

            return(response);
        }
예제 #3
0
        public static DataAccessResponseType ClearStripeWebhooksLog()
        {
            var response = new DataAccessResponseType();

            try
            {
                int amountOfDays = Sahara.Core.Settings.Platform.GarbageCollection.StripeWebhookEventLogDaysToPurge;

                CloudTableClient cloudTableClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.PlatformStorage.CreateCloudTableClient();

                //Create and set retry policy
                //IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(1), 4);
                IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 3);
                cloudTableClient.DefaultRequestOptions.RetryPolicy = linearRetryPolicy;

                CloudTable cloudTable = cloudTableClient.GetTableReference("stripewebhookeventslog");

                cloudTable.CreateIfNotExists();

                TableQuery <TableEntity> query = new TableQuery <TableEntity>()
                                                 .Where(TableQuery.GenerateFilterConditionForDate("DateTimeUTC", QueryComparisons.LessThanOrEqual, DateTimeOffset.UtcNow.AddDays(amountOfDays * -1)));

                var stripeWebhooks = cloudTable.ExecuteQuery(query);

                int count = stripeWebhooks.Count();

                foreach (var log in stripeWebhooks)
                {
                    cloudTable.Execute(TableOperation.Delete(log));
                }

                if (count > 0)
                {
                    //Log Garbage Collection
                    PlatformLogManager.LogActivity(
                        CategoryType.GarbageCollection,
                        ActivityType.GarbageCollection_StripeEventLog,
                        "Purged " + count.ToString("#,##0") + " item(s) from the stripe webhook events logs",
                        count.ToString("#,##0") + " stripe webhook event(s) past " + amountOfDays + " days have been purged"
                        );
                }

                response.isSuccess = true;
            }
            catch (Exception e)
            {
                //Log exception and email platform admins
                PlatformExceptionsHelper.LogExceptionAndAlertAdmins(
                    e,
                    "attempting to clear stripe webhooks log",
                    System.Reflection.MethodBase.GetCurrentMethod()
                    );

                response.isSuccess    = false;
                response.ErrorMessage = e.Message;
            }

            return(response);
        }
        internal static DataAccessResponseType DestroyDocumentCollection(Account account)
        {
            var response = new DataAccessResponseType {
                isSuccess = false
            };

            try
            {
                // Create new stopwatch & begin timing tasks
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();

                #region Connect to the DocumentDB Client & Get Collection Object

                //Get the DocumentDB Client
                //var client = Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient;
                //var dbSelfLink = Sahara.Core.Settings.Azure.DocumentDB.AccountPartitionDatabaseSelfLink;
                //Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.OpenAsync();


                //Build a collection Uri out of the known IDs
                //(These helpers allow you to properly generate the following URI format for Document DB:
                //"dbs/{xxx}/colls/{xxx}/docs/{xxx}"
                Uri collectionUri = UriFactory.CreateDocumentCollectionUri(Sahara.Core.Settings.Azure.DocumentDB.AccountPartitionDatabaseId, account.DocumentPartition);

                #endregion

                #region Delete the document collection for this account

                var result = Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.DeleteDocumentCollectionAsync(collectionUri.ToString()).Result;

                #endregion
            }
            catch
            {
                #region Manual Task Instructions (if failure occurs)

                response.isSuccess = false;

                PlatformLogManager.LogActivity(
                    CategoryType.ManualTask,
                    ActivityType.ManualTask_DocumentDB,
                    "Deletion of Document Collection for closed account '" + account.AccountName + "' failed.",
                    "DocumentPartition: '" + account.DocumentPartition + "' partition for: '" + account.AccountName + "'. Please manually delete the '" + account.DocumentPartition + "' Document Collection",
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    System.Reflection.MethodBase.GetCurrentMethod().ToString()
                    );

                #endregion
            }

            return(response);
        }
예제 #5
0
        public DataAccessResponseType DeletePlatformUser(string userId, string requesterId, RequesterType requesterType, string sharedClientKey)
        {
            // Ensure the clients are certified.
            if (sharedClientKey != Sahara.Core.Platform.Requests.RequestManager.SharedClientKey)
            {
                return(null);
            }

            #region Validate Request

            var requesterName  = string.Empty;
            var requesterEmail = string.Empty;

            var requestResponseType = RequestManager.ValidateRequest(requesterId,
                                                                     requesterType, out requesterName, out requesterEmail,
                                                                     Sahara.Core.Settings.Platform.Users.Authorization.Roles.SuperAdmin,
                                                                     null);

            if (!requestResponseType.isApproved)
            {
                //Request is not approved, send results:
                return(new DataAccessResponseType {
                    isSuccess = false, ErrorMessage = requestResponseType.requestMessage
                });
            }

            #endregion

            var user = PlatformUserManager.GetUser(userId);

            var result = PlatformUserManager.DeleteUser(userId);

            #region Log Platform Activity

            if (result.isSuccess)
            {
                try
                {
                    PlatformLogManager.LogActivity(
                        CategoryType.PlatformUser,
                        ActivityType.PlatformUser_Deleted,
                        "User deleted",
                        requesterName + " deleted " + user.FullName + "'s account",
                        null,
                        null,
                        requesterId,
                        requesterName,
                        requesterEmail
                        );
                }
                catch { }
            }

            #endregion

            return(result);
        }
예제 #6
0
        /// <summary>
        /// Helper function to Logs exceptions AND send emails to alert platform admins
        /// </summary>
        /// <param name="exception"></param>
        /// <param name="details"></param>
        /// <param name="codeLocation"></param>
        /// <param name="accountId"></param>
        /// <param name="accountName"></param>
        /// <param name="serializedObject"></param>
        /// <returns></returns>
        public static bool LogExceptionAndAlertAdmins(Exception exception, string attemptedAction, MethodBase methodBase, string accountId = null, string accountName = null)
        {
            var serializedException = JsonConvert.SerializeObject(exception);

            attemptedAction = "An exception occurred while " + attemptedAction;

            #region Log The Error

            PlatformLogManager.LogActivity(

                CategoryType.Error,
                ActivityType.Error_Exception,
                exception.Message,
                attemptedAction,
                accountId,
                accountName,
                null,
                null,
                null,
                null,
                methodBase.ReflectedType.FullName + "." + methodBase.Name,
                serializedException
                );

            #endregion


            #region Email Platform Admins

            EmailManager.Send(
                Settings.Endpoints.Emails.PlatformEmailAddresses,
                Settings.Endpoints.Emails.FromExceptions,
                "Platform Exception",
                "Exception Alert!",

                "Exception location: <b>" + methodBase.ReflectedType.FullName + "." + methodBase.Name + "</b>" +
                "<br/><br/>" +
                attemptedAction +
                "<br/><br/><b>" +
                exception.Message +
                "</b><br/><br/>" +
                accountId +
                "<br/><br/>" +
                accountName +
                "<br/><br/>" +
                serializedException,

                true,
                true

                );

            #endregion


            return(true);
        }
예제 #7
0
        internal static DataAccessResponseType DestroySchema(string schemaName, string databasePartitionName)
        {
            var response = new DataAccessResponseType();

            //SqlCommand sqlCommand = new SqlCommand("DestroySchema", Sahara.Core.Settings.Azure.Databases.DatabaseConnections.DatabasePartitionSqlConnection(databasePartitionName));
            SqlCommand sqlCommand = Sahara.Core.Settings.Azure.Databases.DatabaseConnections.DatabasePartitionSqlConnection(databasePartitionName).CreateCommand();

            sqlCommand.CommandText = "DestroySchema";


            try
            {
                sqlCommand.CommandType = System.Data.CommandType.StoredProcedure;

                sqlCommand.Parameters.Add(new SqlParameter("@SchemaName", schemaName));
                sqlCommand.Parameters.Add(new SqlParameter("@WorkTest", 'w'));

                sqlCommand.Connection.OpenWithRetry();

                sqlCommand.ExecuteNonQueryWithRetry();

                sqlCommand.Connection.Close();

                response.isSuccess      = true;
                response.SuccessMessage = "Schema '" + schemaName + "', and all associated object have been destroyed on '" + databasePartitionName + "'";
            }
            catch (Exception e)
            {
                //Log exception and email platform admins
                PlatformExceptionsHelper.LogExceptionAndAlertAdmins(
                    e,
                    "attempting to destroy for: " + schemaName,
                    System.Reflection.MethodBase.GetCurrentMethod()
                    );

                PlatformLogManager.LogActivity(
                    CategoryType.ManualTask,
                    ActivityType.ManualTask_SQL,
                    "Stored Procedure 'DestroySchema' Failed on the '" + databasePartitionName + "' partition for schema '" + schemaName + "'",
                    sqlCommand.ToString(),
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    System.Reflection.MethodBase.GetCurrentMethod().ToString()
                    );

                response.isSuccess    = false;
                response.ErrorMessage = e.Message;
            }

            return(response);
        }
예제 #8
0
        public DataAccessResponseType UpdatePlatformUserPassword(string email, string currentPassword, string newPassword, string requesterId, RequesterType requesterType, string sharedClientKey)
        {
            // Ensure the clients are certified.
            if (sharedClientKey != Sahara.Core.Platform.Requests.RequestManager.SharedClientKey)
            {
                return(null);
            }

            #region Validate Request

            var requesterName  = string.Empty;
            var requesterEmail = string.Empty;

            var requestResponseType = RequestManager.ValidateRequest(requesterId,
                                                                     requesterType, out requesterName, out requesterEmail,
                                                                     Sahara.Core.Settings.Platform.Users.Authorization.Roles.SuperAdmin,
                                                                     null);

            if (!requestResponseType.isApproved)
            {
                //Request is not approved, send results:
                return(new DataAccessResponseType {
                    isSuccess = false, ErrorMessage = requestResponseType.requestMessage
                });
            }

            #endregion

            var result = PlatformUserManager.ChangePassword(email, currentPassword, newPassword);

            #region Log Platform Activity

            if (result.isSuccess)
            {
                try
                {
                    PlatformLogManager.LogActivity(
                        CategoryType.PlatformUser,
                        ActivityType.PlatformUser_Invited,
                        "Password changed",
                        requesterName + " has updated their password",
                        null,
                        null,
                        requesterId,
                        requesterName,
                        requesterEmail
                        );
                }
                catch { }
            }

            #endregion

            return(result);
        }
예제 #9
0
        public DataAccessResponseType CreatePlatformUser(string email, string firstName, string lastName, string password, string roleName, string requesterId, RequesterType requesterType, string sharedClientKey)
        {
            // Ensure the clients are certified.
            if (sharedClientKey != Sahara.Core.Platform.Requests.RequestManager.SharedClientKey)
            {
                return(null);
            }

            #region Validate Request

            var requesterName  = string.Empty;
            var requesterEmail = string.Empty;

            var requestResponseType = RequestManager.ValidateRequest(requesterId,
                                                                     requesterType, out requesterName, out requesterEmail,
                                                                     Sahara.Core.Settings.Platform.Users.Authorization.Roles.SuperAdmin,
                                                                     null);

            if (!requestResponseType.isApproved)
            {
                //Request is not approved, send results:
                return(new DataAccessResponseType {
                    isSuccess = false, ErrorMessage = requestResponseType.requestMessage
                });
            }

            #endregion

            var result = PlatformUserManager.CreatePlatformUser(email, firstName, lastName, password, roleName);

            #region Log Platform Activity

            if (result.isSuccess)
            {
                try
                {
                    PlatformLogManager.LogActivity(
                        CategoryType.PlatformUser,
                        ActivityType.PlatformUser_Created,
                        "User created",
                        requesterName + " created new user: '******'",
                        null,
                        null,
                        requesterId,
                        requesterName,
                        requesterEmail
                        );
                }
                catch { }
            }

            #endregion

            return(result);
        }
        /// <summary>
        /// Returns true if event has been logged in the past
        /// </summary>
        /// <returns></returns>
        internal static bool HasEventBeenLogged(string eventId)
        {
            var stripeWebhookEventsLog = GetWebhookEvent(eventId);

            if (stripeWebhookEventsLog != null)
            {
                //Event exists and has been run by our webhook API, increase retry count by 1 and return true:

                try
                {
                    //Update retry count +1
                    stripeWebhookEventsLog.RetryCount = stripeWebhookEventsLog.RetryCount + 1;
                    TableOperation operation = TableOperation.InsertOrReplace(stripeWebhookEventsLog);

                    //Create the cloudtable instance and  name for the entity operate against:
                    var cloudTableClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.PlatformStorage.CreateCloudTableClient();

                    //Create and set retry policy
                    //IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(1), 4);
                    IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 5);
                    cloudTableClient.DefaultRequestOptions.RetryPolicy = linearRetryPolicy;

                    stripeWebhookEventsLog.cloudTable = cloudTableClient.GetTableReference(StripeWebhookEventsLogManager.StripeWebhookEventsLogTableName);
                    stripeWebhookEventsLog.cloudTable.CreateIfNotExists();

                    stripeWebhookEventsLog.cloudTable.Execute(operation);
                }
                catch (Exception e)
                {
                    PlatformLogManager.LogActivity(
                        CategoryType.Error,
                        ActivityType.Error_Exception,
                        "An exception occurred while attempting to increment retry count on an existing stripe event log for idempotenancy",
                        "Incrementing retry count on stripe idempotent log for: " + stripeWebhookEventsLog.EventID,
                        null,
                        null,
                        null,
                        null,
                        null,
                        null,
                        null,
                        JsonConvert.SerializeObject(e)
                        );
                }

                //return true:
                return(true);
            }
            else
            {
                //Event does not exists, return false;
                return(false);
            }
        }
예제 #11
0
        /// <summary>
        /// Helper function to Logs exceptions AND send emails to alert platform admins
        /// </summary>
        /// <param name="error"></param>
        /// <param name="details"></param>
        /// <param name="codeLocation"></param>
        /// <param name="accountId"></param>
        /// <param name="accountName"></param>
        /// <param name="serializedObject"></param>
        /// <returns></returns>
        public static bool LogErrorAndAlertAdmins(string error, string attemptedAction, MethodBase methodBase, string accountId = null, string accountName = null)
        {
            attemptedAction = "An error occurred while " + attemptedAction;

            #region Log The Error

            PlatformLogManager.LogActivity(

                CategoryType.Error,
                ActivityType.Error_Other,
                error,
                attemptedAction,
                accountId,
                accountName,
                null,
                null,
                null,
                null,
                methodBase.ReflectedType.FullName + "." + methodBase.Name,
                null
                );

            #endregion


            #region Email Platform Admins

            EmailManager.Send(
                Settings.Endpoints.Emails.PlatformEmailAddresses,
                Settings.Endpoints.Emails.FromExceptions,
                "Platform Error",
                "Error Alert!",

                "Error location: <b>" + methodBase.ReflectedType.FullName + "." + methodBase.Name + "</b>" +
                "<br/><br/>" +
                attemptedAction +
                "<br/><br/><b>" +
                error +
                "</b><br/><br/>" +
                accountId +
                "<br/><br/>" +
                accountName,

                true,
                true

                );

            #endregion


            return(true);
        }
예제 #12
0
        public static DataAccessResponseType ClearIntermediaryStorage()
        {
            var response = new DataAccessResponseType();

            var daysAgo = (Sahara.Core.Settings.Platform.GarbageCollection.IntermediaryStorageContainerDaysToPurge * -1);

            try
            {
                //Clients that wish to save source files to intermediary blob storage mush use the following date format to name the container for custodial garbage collection to take place.
                var date          = DateTime.UtcNow.AddDays(daysAgo);
                var containerName = date.ToShortDateString().Replace("/", "-");

                //Delete Storage Containers on Intermediary Labeled from "X" days ago
                CloudBlobClient blobClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.IntermediateStorage.CreateCloudBlobClient();

                //Create and set retry policy
                IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromMilliseconds(500), 8);
                blobClient.DefaultRequestOptions.RetryPolicy = exponentialRetryPolicy;


                if (blobClient.GetContainerReference(containerName).Exists())
                {
                    blobClient.GetContainerReference(containerName).DeleteIfExists();

                    //Log Garbage Collection
                    PlatformLogManager.LogActivity(
                        CategoryType.GarbageCollection,
                        ActivityType.GarbageCollection_IntermediaryStorage,
                        "Purged the '" + containerName + "' intermediary storage container",
                        "An intermediary storage container older than " + Sahara.Core.Settings.Platform.GarbageCollection.IntermediaryStorageContainerDaysToPurge + " days has been purged"
                        );
                }


                response.isSuccess = true;
            }
            catch (Exception e)
            {
                //Log exception and email platform admins
                PlatformExceptionsHelper.LogExceptionAndAlertAdmins(
                    e,
                    "attempting to purge intermediary data past " + Sahara.Core.Settings.Platform.GarbageCollection.IntermediaryStorageContainerDaysToPurge + " days old",
                    System.Reflection.MethodBase.GetCurrentMethod()
                    );

                response.isSuccess    = false;
                response.ErrorMessage = e.Message;
            }

            return(response);
        }
        internal static DataAccessResponseType DestroySearchIndexes(Account account)
        {
            var response = new DataAccessResponseType {
                isSuccess = false
            };

            try
            {
                // Create new stopwatch & begin timing tasks
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();


                #region Delete the search indexes for this account

                //SearchServiceClient searchServiceClient = Settings.Azure.Search.AccountsSearchServiceClient;
                //searchServiceClient.Indexes.Delete(account.ProductSearchIndex);

                //Using partition for this account:
                SearchServiceClient searchServiceClient = Settings.Azure.Search.GetSearchPartitionClient(account.SearchPartition);
                searchServiceClient.Indexes.Delete(account.ProductSearchIndex);

                #endregion
            }
            catch
            {
                #region Manual Task Instructions (if failure occurs)

                response.isSuccess = false;

                PlatformLogManager.LogActivity(
                    CategoryType.ManualTask,
                    ActivityType.ManualTask_DocumentDB,
                    "Deletion of Search Indexes for closed account '" + account.AccountName + "' failed.",
                    "Search Indexes for: '" + account.AccountNameKey + "' will need to be manually deleted in the Azure portal.",
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    System.Reflection.MethodBase.GetCurrentMethod().ToString()
                    );

                #endregion
            }

            return(response);
        }
        internal static DataAccessResponseType DestroyTableStorageData(Account account)
        {
            var response = new DataAccessResponseType {
                isSuccess = false
            };

            //Loop through all tables named by schema for this account and delete
            //CloudTableClient cloudTableClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.AccountsStorage.CreateCloudTableClient();
            CloudTableClient cloudTableClient = Settings.Azure.Storage.GetStoragePartitionAccount(account.StoragePartition).CreateCloudTableClient();

            //Create and set retry policy
            IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(1), 16);

            //IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 3);
            cloudTableClient.DefaultRequestOptions.RetryPolicy = exponentialRetryPolicy;

            IEnumerable <CloudTable> tables = cloudTableClient.ListTables(Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(account.AccountID.ToString()));

            foreach (CloudTable table in tables)
            {
                try
                {
                    table.Delete();
                }
                catch
                {
                    response.isSuccess = false;

                    PlatformLogManager.LogActivity(
                        CategoryType.ManualTask,
                        ActivityType.ManualTask_TableStorage,
                        "Table(s) Deletion Failed for schema" + Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(account.AccountID.ToString()),
                        "Please delete all tables for schema '" + Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(account.AccountID.ToString()) + "' manually.",
                        null,
                        null,
                        null,
                        null,
                        null,
                        null,
                        System.Reflection.MethodBase.GetCurrentMethod().ToString()
                        );
                }
            }

            return(response);
        }
예제 #15
0
        internal static DataAccessResponseType DeleteTag(Account account, string tagName)
        {
            var response = new DataAccessResponseType();

            //CloudTableClient cloudTableClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.AccountsStorage.CreateCloudTableClient();
            CloudTableClient cloudTableClient = Settings.Azure.Storage.GetStoragePartitionAccount(account.StoragePartition).CreateCloudTableClient();

            //Create and set retry policy
            //IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(1), 4);
            IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 4);

            cloudTableClient.DefaultRequestOptions.RetryPolicy = linearRetryPolicy;

            CloudTable cloudTable = cloudTableClient.GetTableReference(Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(account.AccountID.ToString()) + TagsTableName);

            cloudTable.CreateIfNotExists();

            try
            {
                TagTableEntity tagEntity = cloudTable.CreateQuery <TagTableEntity>().Where(t => t.PartitionKey == tagName).FirstOrDefault();

                TableResult deleteResult = cloudTable.Execute(TableOperation.Delete(tagEntity));

                response.isSuccess = true;
            }
            catch (Exception e)
            {
                PlatformLogManager.LogActivity(
                    CategoryType.Error,
                    ActivityType.Error_Exception,
                    e.Message,
                    "Exception while attempting to delete tag '" + tagName + "'",
                    account.AccountID.ToString(),
                    account.AccountName,
                    null,
                    null,
                    null,
                    null,
                    System.Reflection.MethodBase.GetCurrentMethod().ToString(),
                    null
                    );
            }

            return(response);
        }
        internal static DataAccessResponseType DestroyBlobStorageData(Account account)
        {
            var response = new DataAccessResponseType {
                isSuccess = true
            };

            //CloudBlobClient blobClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.AccountsStorage.CreateCloudBlobClient();
            CloudBlobClient blobClient = Sahara.Core.Settings.Azure.Storage.GetStoragePartitionAccount(account.StoragePartition).CreateCloudBlobClient();

            //Create and set retry policy
            IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromMilliseconds(500), 8);

            blobClient.DefaultRequestOptions.RetryPolicy = exponentialRetryPolicy;

            CloudBlobContainer blobContainer = blobClient.GetContainerReference(account.AccountID.ToString());

            //CloudBlobContainer blobContainer = blobClient.GetContainerReference(account.AccountNameKey);

            try
            {
                blobContainer.DeleteIfExists();
            }
            catch
            {
                response.isSuccess = false;

                PlatformLogManager.LogActivity(
                    CategoryType.ManualTask,
                    ActivityType.ManualTask_BlobStorage,
                    "Blob Container Deletion Failed",
                    "Please delete the top level container '" + account.AccountID.ToString() + "' manually.",
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    System.Reflection.MethodBase.GetCurrentMethod().ToString()
                    );
            }


            return(response);
        }
예제 #17
0
        /// <summary>
        /// Helper function to log when an account reaches a limitation AND send emails to alert platform admins for upsell opportunities
        /// </summary>
        /// <param name="limitationReached"></param>
        /// <param name="accountId"></param>
        /// <param name="accountName"></param>
        /// <returns></returns>
        public static bool LogLimitationAndAlertAdmins(string limitationObjectName, string accountId = null, string accountName = null)
        {
            #region Log The Limitation

            PlatformLogManager.LogActivity(

                CategoryType.Account,
                ActivityType.Account_LimitationReached,
                accountName + " has reached an account limitation",
                accountName + " has reached a limitation on their maximum allowed " + limitationObjectName,
                accountId,
                accountName,
                null,
                null,
                null,
                null,
                null,
                null
                );

            #endregion

            #region Email Platform Admins

            EmailManager.Send(
                Settings.Endpoints.Emails.PlatformEmailAddresses,
                Settings.Endpoints.Emails.FromPlatform,
                "Account Limitations",
                "Account Limitation Reached!",
                "<a href='http://" + Sahara.Core.Settings.Endpoints.URLs.PlatformDomain + "/account/" + accountId + "'><strong>" + accountName + "</strong></a> has attempted to go past a plan limitation on their maximum allowed " + limitationObjectName,
                true,
                true

                );

            #endregion


            return(true);
        }
예제 #18
0
        /// <summary>
        /// Helper function to log when an account is closed AND send emails to alert platform admins for verification purposes
        /// </summary>
        /// <param name="accountId"></param>
        /// <param name="accountName"></param>
        /// <param name="accountNameKey"></param>
        /// <param name="userEmail"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static bool LogAccountClosureAndAlertAdmins(string accountId, string accountName, string accountNameKey, string userName, string userId, string userEmail, bool isPaidAccount)
        {
            #region Log The Limitation

            PlatformLogManager.LogActivity(

                CategoryType.Account,
                ActivityType.Account_ClosureRequested,
                accountName + " has requested closure",
                accountName + " has closure request initiated by " + userName + "(" + userId + " | " + userEmail + ")",
                accountId,
                accountName,
                null,
                null,
                null,
                null,
                null,
                null
                );

            #endregion

            #region Email Platform Admins

            EmailManager.Send(
                Settings.Endpoints.Emails.PlatformEmailAddresses,
                Settings.Endpoints.Emails.FromPlatform,
                "Account Closure Request",
                accountName + " has requested account closure",
                "<a href='http://" + Sahara.Core.Settings.Endpoints.URLs.PlatformDomain + "/account/" + accountNameKey + "'><strong>" + accountName + "</strong></a> has been closed by " + userName + "(" + userId + " | " + userEmail + ")",
                true,
                true

                );

            #endregion


            return(true);
        }
        internal static bool ClearReminderEmailsLog(int amountOfDays)
        {
            CloudTableClient cloudTableClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.PlatformStorage.CreateCloudTableClient();

            //Create and set retry policy
            //IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(1), 4);
            IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 3);

            cloudTableClient.DefaultRequestOptions.RetryPolicy = linearRetryPolicy;

            CloudTable cloudTable = cloudTableClient.GetTableReference(ReminderEmailsCardExpirationLogTableName);

            cloudTable.CreateIfNotExists();

            TableQuery <CardExpirationEmailRemindersLogTableEntity> query = new TableQuery <CardExpirationEmailRemindersLogTableEntity>()
                                                                            .Where(TableQuery.GenerateFilterConditionForDate("DateTimeUTC", QueryComparisons.LessThanOrEqual, DateTimeOffset.UtcNow.AddDays(amountOfDays * -1)));

            var cardExirationReminderEmails = cloudTable.ExecuteQuery(query);

            int count = cardExirationReminderEmails.Count();

            foreach (var log in cardExirationReminderEmails)
            {
                cloudTable.Execute(TableOperation.Delete(log));
            }

            if (count > 0)
            {
                //Log Garbage Collection
                PlatformLogManager.LogActivity(
                    CategoryType.GarbageCollection,
                    ActivityType.GarbageCollection_CreditCardExpirationRemindersLog,
                    "Purged " + count.ToString("#,##0") + " item(s) from the credit card expiration reminders logs",
                    count.ToString("#,##0") + " credit card expiration reminder(s) past " + Sahara.Core.Settings.Platform.GarbageCollection.CreditCardExpirationReminderEmailsLogDaysToPurge + " days have been purged"
                    );
            }

            return(true);
        }
        public static DataAccessResponseType DeprovisionAccount(Account account)
        {
            DataAccessResponseType response = new DataAccessResponseType();

            if (account.AccountID == Guid.Empty)
            {
                response.isSuccess    = false;
                response.ErrorMessage = "No account to deprovision";
                return(response);
            }

            try
            {
                // 0. Get Account Users:
                account.Users = AccountUserManager.GetUsers(account.AccountID.ToString());



                #region LOG ACTIVITY (Deprovisioning Started)


                if (account.Provisioned)
                {
                    PlatformLogManager.LogActivity(
                        CategoryType.Account,
                        ActivityType.Account_Deprovisioning_Started,
                        "Deprovisioning of '" + account.AccountName + "' has started",
                        "AccountID: '" + account.AccountID +
                        "' SqlPartition: '" + account.SqlPartition +
                        "' DocumentPartition: '" + account.DocumentPartition +
                        "' StripeCustomerID: '" + account.StripeCustomerID +
                        "'"
                        );
                }
                else if (!account.Provisioned)
                {
                    //Account has not been provisioned, only delete the account and user objects, This will be a simple purge and not a full deprovisioning
                    PlatformLogManager.LogActivity(CategoryType.Account, ActivityType.Account_Purge_Started, "Purging of unprovisioned account '" + account.AccountName + "' has started", "AccountID: '" + account.AccountID + "' Account Owner: '" + account.Users[0].UserName + "'");
                }

                #endregion


                // Owners of accounts that have been provisioned will get an email, create a list of owner emails before all users are delted
                var accountOwnerEmails = AccountManager.GetAccountOwnerEmails(account.AccountID.ToString());

                string accountOwners = string.Empty;

                foreach (string ownerEmail in accountOwnerEmails)
                {
                    accountOwners += ownerEmail + " ";
                }


                #region STEPS 1-3 DELETE ACCOUNT USERS AND ACCOUNT

                // 1. Delete All Account Users
                AccountDeprovisioning.DeleteAllAccountUsers(account);

                // 2. Delete Account
                AccountDeprovisioning.DeleteAccount(account);

                // 3. Delete Customer in Stripe if the account has a StripeCustomerID
                if (account.StripeCustomerID != null)
                {
                    try
                    {
                        var stripeManager = new StripeManager();
                        stripeManager.DeleteCustomer(account.StripeCustomerID);
                    }
                    catch
                    {
                    }
                }

                #endregion

                if (!account.Provisioned)
                {
                    #region Log closure if account is not provisioned
                    //Account has never been provisioned, since we already deleted the account and all associated users, we are done. Log activity completion and return result:
                    PlatformLogManager.LogActivity(
                        CategoryType.Account,
                        ActivityType.Account_Purged,
                        "Purging of unprovisioned account '" + account.AccountName + "' has completed",
                        "Account Owners: '" + accountOwners + "'",
                        account.AccountID.ToString(),
                        account.AccountName,
                        null,
                        null,
                        null,
                        null,
                        null,
                        JsonConvert.SerializeObject(account)
                        );


                    //Log the closed account
                    PlatformLogManager.LogActivity(
                        CategoryType.Account,
                        ActivityType.Account_Closed,
                        "Unprovisioned",
                        account.AccountNameKey,
                        account.AccountID.ToString(),
                        account.AccountName,
                        null,
                        null,
                        null,
                        null,
                        null,
                        JsonConvert.SerializeObject(account));

                    response.isSuccess      = true;
                    response.SuccessMessage = "Purging of account '" + account.AccountID + "' Complete!";


                    #endregion
                }
                else
                {
                    // 4. Clear SQL Data Schema &
                    AccountDeprovisioning.DestroySqlSchemaAndTables(account);

                    // 5. Clear Table Storage Data
                    AccountDeprovisioning.DestroyTableStorageData(account);

                    // 6. Clear Blob Storage Data
                    AccountDeprovisioning.DestroyBlobStorageData(account);

                    // 7. Clear Document Data (Retired)
                    AccountDeprovisioning.DestroyDocumentCollection(account);

                    // 8. Clear Search Indexes
                    AccountDeprovisioning.DestroySearchIndexes(account);

                    // 9. Decriment both STORAGE & SEARCH Partitions
                    Sql.Statements.UpdateStatements.UpdatePartitionsTenantCounts(account.StoragePartition, account.SearchPartition);

                    // 10. Log Activity
                    #region Logging


                    PlatformLogManager.LogActivity(
                        CategoryType.GarbageCollection,
                        ActivityType.GarbageCollection_ClosedAccounts,
                        "All resources for account '" + account.AccountName + "' have been destroyed",
                        "Purged resources now available to new accounts",
                        account.AccountID.ToString(),
                        account.AccountName,
                        null,
                        null,
                        null,
                        null,
                        null,
                        JsonConvert.SerializeObject(account)
                        );


                    PlatformLogManager.LogActivity(
                        CategoryType.Account,
                        ActivityType.Account_Deprovisioned,
                        "Deprovisioning of '" + account.AccountName + "' has completed",
                        "SqlPartition: '" + account.SqlPartition + "'",
                        account.AccountID.ToString(),
                        account.AccountName,
                        null,
                        null,
                        null,
                        null,
                        null,
                        JsonConvert.SerializeObject(account)
                        );

                    //Log the closed account
                    PlatformLogManager.LogActivity(
                        CategoryType.Account,
                        ActivityType.Account_Closed,
                        "Deprovisioned",
                        account.AccountNameKey + " | " + account.PaymentPlanName,
                        account.AccountID.ToString(),
                        account.AccountName,
                        null,
                        null,
                        null,
                        null,
                        null,
                        JsonConvert.SerializeObject(account));

                    #endregion

                    // 11. Email all account users regarding closure:
                    EmailManager.Send(
                        accountOwnerEmails,
                        Settings.Endpoints.Emails.FromAlerts,
                        Settings.Copy.EmailMessages.DeprovisioningComplete.FromName,
                        Settings.Copy.EmailMessages.DeprovisioningComplete.Subject,
                        String.Format(Settings.Copy.EmailMessages.DeprovisioningComplete.Body, account.AccountName),
                        true);

                    // 12. Destroy ALL caches associated with an account
                    AccountManager.DestroyAccountCaches(account.AccountID.ToString(), account.AccountNameKey, account.StripeCustomerID);

                    // 13. Destroy subdomains
                    try
                    {
                        var cloudFlareResult = CloudFlareManager.RemoveSubdomains(account.AccountNameKey);

                        if (cloudFlareResult.isSuccess == false)
                        {
                            //Log exception and email platform admins
                            PlatformExceptionsHelper.LogErrorAndAlertAdmins(
                                cloudFlareResult.ErrorMessage,
                                "attempting to remove cloudflare subdomains for the '" + account.AccountName + "' account during deprovisioning.",
                                System.Reflection.MethodBase.GetCurrentMethod(),
                                account.AccountID.ToString(),
                                account.AccountName
                                );
                        }
                    }
                    catch (Exception e)
                    {
                        //Log exception and email platform admins
                        PlatformExceptionsHelper.LogExceptionAndAlertAdmins(
                            e,
                            "attempting to remove cloudflare subdomains for the '" + account.AccountName + "' account during deprovisioning.",
                            System.Reflection.MethodBase.GetCurrentMethod(),
                            account.AccountID.ToString(),
                            account.AccountName
                            );
                    }

                    response.isSuccess      = true;
                    response.SuccessMessage = "Deprovisioning of account '" + account.AccountID + "' Complete!";
                }

                //TODO: Log purged account into ClosedAccounts Table
            }
            catch (Exception e)
            {
                #region LOG ERROR (Deprovisioning Errors)

                //Log exception and email platform admins
                PlatformExceptionsHelper.LogExceptionAndAlertAdmins(
                    e,
                    "attempting to deprovision or purge account: " + account.AccountName,
                    System.Reflection.MethodBase.GetCurrentMethod(),
                    account.AccountID.ToString(),
                    account.AccountName
                    );

                #endregion

                response.isSuccess    = false;
                response.ErrorMessage = e.Message;
            }

            // Archive the closed account
            //ClosedAccountsStorageManager.ArchiveClosedAccount(account);


            return(response);
        }
예제 #21
0
        /// <summary>
        /// This is the entry point of the service host process.
        /// </summary>
        private static void Main()
        {
            try
            {
                // The ServiceManifest.XML file defines one or more service type names.
                // Registering a service maps a service type name to a .NET type.
                // When Service Fabric creates an instance of this service type,
                // an instance of the class is created in this host process.

                #region Startup Tasks

                // 1.)   ------
                System.Net.ServicePointManager.DefaultConnectionLimit = 12 * Environment.ProcessorCount; //<-- Allows us to marshal up more SearchService/SearchIndex Clients to avoid exhausting sockets.

                #region Working w/ Service Fabric Enviornment Variables

                //Pull in enviornment variables: -----------------------------------------------------------
                //var hostId = Environment.GetEnvironmentVariable("Fabric_ApplicationHostId");
                //var appHostType = Environment.GetEnvironmentVariable("Fabric_ApplicationHostType");
                //var tyoeEndpoint = Environment.GetEnvironmentVariable("Fabric_Endpoint_[YourServiceName]TypeEndpoint");
                //var nodeName = Environment.GetEnvironmentVariable("Fabric_NodeName");

                //Or print them all out (Fabric Only):

                /*
                 * foreach (DictionaryEntry de in Environment.GetEnvironmentVariables())
                 * {
                 *  if (de.Key.ToString().StartsWith("Fabric"))
                 *  {
                 *      ServiceEventSource.Current.ServiceMessage(this.Context, " Environment variable {0} = {1}", de.Key, de.Value);
                 *  }
                 * }
                 */

                //EVERY SINGLE ONE:

                /*
                 * foreach (DictionaryEntry de in Environment.GetEnvironmentVariables())
                 * {
                 *  ServiceEventSource.Current.ServiceMessage(this.Context, " Environment variable {0} = {1}", de.Key, de.Value);
                 *
                 * }*/

                #endregion


                // 2.)   ------
                var nodeName = Environment.GetEnvironmentVariable("Fabric_NodeName");

                // 3.)   ------
                // string environment = "production"; //RoleEnvironment.GetConfigurationSettingValue("Environment");
                string environment = Environment.GetEnvironmentVariable("Env").ToLower();
                Sahara.Core.Settings.Startup.Initialize(environment);

                Sahara.Core.Settings.Azure.CurrentRoleInstance.Name = nodeName; // RoleEnvironment.CurrentRoleInstance.Role.Name;
                //Sahara.Core.Settings.Azure.CurrentRoleInstance.Id = nodeName; //instanceIndex;

                // TODO: Track down use of Sahara.Core.Settings.Azure.CurrentRoleInstance.Id and replace with nodeName or anotehr var type


                //Trace.TraceInformation("Sahara.CoreServices.WcfEndpoints node:" + nodeName + " entry point called on env: " + environment);



                //Log Activity:
                PlatformLogManager.LogActivity(
                    CategoryType.Worker,
                    ActivityType.Worker_Status_Update,
                    "Platform Worker starting on node '" + nodeName + "' (env: " + environment + ")....",
                    "WORKER.PlatformWorker entry point called on env: " + environment + " (node:" + nodeName + ") (env: " + environment + ")"
                    );


                #endregion

                ServiceRuntime.RegisterServiceAsync("PlatformWorkerType",
                                                    context => new PlatformWorker(context)).GetAwaiter().GetResult();

                ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(PlatformWorker).Name);

                // Prevents this host process from terminating so services keep running.
                Thread.Sleep(Timeout.Infinite);
            }
            catch (Exception e)
            {
                ServiceEventSource.Current.ServiceHostInitializationFailed(e.ToString());
                throw;
            }
        }
예제 #22
0
        public static DataAccessResponseType ProvisionPlatform(string FirstName, string LastName, string Email, string password)
        {
            // Begin timing task
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            DataAccessResponseType response = new DataAccessResponseType();

            if (!isPlatformInitialized())
            {
                //Generate Databases & Schemas
                PlatformInitialization platformInitialization = new PlatformInitialization();
                response = platformInitialization.InitializePlatform();

                if (response.isSuccess)
                {
                    try
                    {
                        //Create initial Platform User & Assign to SuperAdmin Role
                        var createUserResult = PlatformUserManager.CreatePlatformUser(Email, FirstName, LastName, password, Sahara.Core.Settings.Platform.Users.Authorization.Roles.SuperAdmin);
                        if (createUserResult.isSuccess)
                        {
                            //Replicate Payment Plans to Stripe Account:
                            //StripeInitialization.SeedPaymentPlans();
                            var stripePlansResponse = PaymentPlanManager.DuplicatePlansToStripe();

                            if (!stripePlansResponse.isSuccess)
                            {
                                response.isSuccess    = false;
                                response.ErrorMessage = "An error occured when creating Stripe plans";
                                return(response);
                            }


                            /*======================================
                             *   Create AccountPartition Document Database
                             * ========================================*/

                            /*  Retired ------------------*/

                            //var client = Sahara.Core.Settings.Azure.DocumentDB.DocumentClients.AccountDocumentClient;
                            var databasename = Sahara.Core.Settings.Azure.DocumentDB.AccountPartitionDatabaseId;

                            Database accountDatabase = Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.CreateDatabaseQuery().Where(db => db.Id == databasename).ToArray().FirstOrDefault();
                            if (accountDatabase == null)
                            {
                                //Create if not exists
                                accountDatabase = Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.CreateDatabaseAsync(new Database {
                                    Id = databasename
                                }).Result;
                            }



                            /*======================================
                             *   Clear all logs ()
                             * ========================================*/

                            //PlatformLogManager.ClearLogs();

                            /*======================================
                             *   Log Initilization of Platform
                             * ========================================*/

                            stopwatch.Stop();

                            PlatformLogManager.LogActivity(
                                CategoryType.Platform,
                                ActivityType.Platform_Initialized,
                                "Platform initilized by: " + FirstName + " " + LastName + " (" + Email + ")",
                                "Initialization took " + String.Format("{0:0,0.00}", TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds).TotalMinutes) + " minute(s) to complete"
                                );


                            response.isSuccess      = true;
                            response.SuccessMessage = "Platform has been successfully initialized and '" + Email + "' has been registered as the initial platform administrator.";
                        }
                    }
                    catch (Exception e)
                    {
                        response.isSuccess    = false;
                        response.ErrorMessage = e.Message;
                        try
                        {
                            response.ErrorMessages.Add(e.InnerException.Message);
                        }
                        catch
                        {
                        }
                    }
                }

                return(response);
            }
            else
            {
                response.isSuccess    = false;
                response.ErrorMessage = "Platform is already initialized.";
                response.ErrorMessages.Add("If you are attempting to create a new installation on this envionemnt: You must first clear all platfrom components manually.");

                return(response);
            }
        }
예제 #23
0
        /// <summary>
        /// This is the main entry point for your service instance.
        /// </summary>
        /// <param name="cancellationToken">Canceled when Service Fabric needs to shut down this service instance.</param>
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            #region Working w/ Service Fabric Enviornment Variables

            //Pull in enviornment variables: -----------------------------------------------------------
            //var hostId = Environment.GetEnvironmentVariable("Fabric_ApplicationHostId");
            //var appHostType = Environment.GetEnvironmentVariable("Fabric_ApplicationHostType");
            //var tyoeEndpoint = Environment.GetEnvironmentVariable("Fabric_Endpoint_[YourServiceName]TypeEndpoint");
            //var nodeName = Environment.GetEnvironmentVariable("Fabric_NodeName");

            //Or print them all out (Fabric Only):

            /*
             * foreach (DictionaryEntry de in Environment.GetEnvironmentVariables())
             * {
             *  if (de.Key.ToString().StartsWith("Fabric"))
             *  {
             *      ServiceEventSource.Current.ServiceMessage(this.Context, " Environment variable {0} = {1}", de.Key, de.Value);
             *  }
             * }
             */

            //EVERY SINGLE ONE:

            /*
             * foreach (DictionaryEntry de in Environment.GetEnvironmentVariables())
             * {
             *  ServiceEventSource.Current.ServiceMessage(this.Context, " Environment variable {0} = {1}", de.Key, de.Value);
             *
             * }
             */

            #endregion

            //Check if platform is initialized
            bool platformInitialized = PlatformInitializationManager.isPlatformInitialized();

            //Tests/References ------
            ConfigurationPackage configPackage = this.Context.CodePackageActivationContext.GetConfigurationPackageObject("config");
            var    configurationSetting        = configPackage.Settings.Sections["CustodialConfigSection"].Parameters["MyConfigSetting"].Value;
            string environmentVariable         = Environment.GetEnvironmentVariable("MyEnvVariable");

            var nodeName = Environment.GetEnvironmentVariable("Fabric_NodeName");
            ServiceEventSource.Current.ServiceMessage(this.Context, String.Format("{0} waking up on {1}", workerName, nodeName));

            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (platformInitialized)
                {
                    #region RUN TASKS

                    // Create new stopwatch
                    Stopwatch stopwatch = new Stopwatch();

                    // Begin timing tasks
                    stopwatch.Start();


                    #if DEBUG
                    //Trace.TraceInformation("Custodian Working...");
                    #endif

                    //Log
                    //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Tasks_Started,
                    //"Starting Scheduled Tasks");


                    //========================================================================
                    //  TASK 1:   Deprovision Closed Accounts:
                    //========================================================================

                    var deprovisionClosedAccountsResponse = CustodianManager.DeprovisionClosedAccounts();
                    if (deprovisionClosedAccountsResponse.isSuccess)
                    {
                        //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Task, "Task # 4 Complete (Deprovision Closed Accounts)");
                    }
                    else
                    {
                        PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Custodian, "Task # 1 Had Errors (Deprovision Closed Accounts)", deprovisionClosedAccountsResponse.ErrorMessage);
                    }



                    //========================================================================
                    //  TASK 2:   Email Accounts Dunning Reminder(s) About Upcoming Credit Card Expiration Dtes:
                    //========================================================================

                    var creditCardExpirationRemindersResponse = CustodianManager.SendCreditCardExpirationReminders();
                    if (creditCardExpirationRemindersResponse.isSuccess)
                    {
                        //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Task, "Task # 6 Complete (Credit Card Expiration Date Reminders)");
                    }
                    else
                    {
                        PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Custodian, "Task # 2 Had Errors (Credit Card Expiration Date Reminders)", creditCardExpirationRemindersResponse.ErrorMessage);
                    }


                    //========================================================================
                    //  TASK 3:   Clean Up Credit Card Expirations Email Log
                    //========================================================================

                    var creditCardExpirationRemindersLogCleanupResponse = CustodianManager.ClearCreditCardExpirationRemindersLog();
                    if (creditCardExpirationRemindersLogCleanupResponse.isSuccess)
                    {
                        //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Task, "Task # 7 Complete (Cleaned Up Credit Card Expiration Date Reminders Log )");
                    }
                    else
                    {
                        PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Custodian, "Task # 3 Had Errors (Cleaned Up Credit Card Expiration Date Reminders Log )", creditCardExpirationRemindersLogCleanupResponse.ErrorMessage);
                    }



                    //========================================================================
                    //  TASK 4:   Clean up Intermediary Storage of Source Files
                    //========================================================================
                    var intermediaryCleanupResponse = CustodianManager.ClearIntermediaryStorage();
                    if (intermediaryCleanupResponse.isSuccess)
                    {
                        //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Task, "Task # 8 Complete (Intermediary Storage Cleanup)");
                    }
                    else
                    {
                        PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Custodian, "Task # 4 Had Errors (Log Cleanup)", intermediaryCleanupResponse.ErrorMessage);
                    }

                    //========================================================================
                    //  TASK 5:   Clean up Intermediary Storage of Source Files
                    //========================================================================
                    var stripeWebhookEventsCleanupResponse = CustodianManager.ClearStripeWebhooksLog();
                    if (stripeWebhookEventsCleanupResponse.isSuccess)
                    {
                        //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Task, "Task # 8 Complete (Intermediary Storage Cleanup)");
                    }
                    else
                    {
                        PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Custodian, "Task # 5 Had Errors (Log Cleanup)", stripeWebhookEventsCleanupResponse.ErrorMessage);
                    }


                    //========================================================================
                    //  TASK 6:   Ping sites to keep them awake for user traffic:
                    //========================================================================

                    var pingSitesResponse = CustodianManager.PingSites();

                    /*
                     * if (pingSitesResponse.isSuccess)
                     * {
                     *  PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Task, "Task # 6 Complete (Ping Sites)");
                     * }
                     * else
                     * {
                     *  PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Custodian, "Task # 6 Had Errors (Ping sites)", pingSitesResponse.ErrorMessage);
                     * }
                     */

                    //========================================================================
                    //  TASK 7:   Load up subset of account data so it is cached and ready for API calls:
                    //========================================================================


                    var cacheAccountsResponse = CustodianManager.CacheAccountData();



                    //========================================================================
                    //  TASK 0:   Cleanup Logs:
                    //========================================================================

                    var logCleanupResponse = CustodianManager.ClearLogs();
                    if (logCleanupResponse.isSuccess)
                    {
                        //Not yet implemented - is it even necessary?
                        //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Task, "Task # 0 Complete (Log Cleanup)");
                    }
                    else
                    {
                        PlatformLogManager.LogActivity(CategoryType.Error, ActivityType.Error_Custodian, "Task # 0 Had Errors (Log Cleanup)", logCleanupResponse.ErrorMessage);
                    }



                    //========================================================================
                    //  TASK 10:   Cleanup Source Images:
                    //========================================================================



                #if DEBUG
                    //Trace.TraceInformation("Tasks complete.");
                    //Trace.TraceInformation("Custodian sleeping for: " + Sahara.Core.Settings.Platform.Custodian.Frequency.Description);
                #endif

                    stopwatch.Stop();

                    //PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Scheduled_Tasks_Complete,
                    //"Scheduled Tasks Started & Completed in " + stopwatch.ElapsedMilliseconds.ToString("#,##0") + " milliseconds");

                    //Invalidate the accounts snapshot cache so platform admins see any account updates quicker:
                    PlatformSnapshotsManager.DestroyAccountSnapshotCache();

                    //Sleep for 4 seconds to put next_run log activity at the top:
                    //Thread.Sleep(4000); <-- No longer required since we are only logging one activity

                    //Sleep for 4 seconds to put next_run log activity at the top:
                    //Thread.Sleep(4000); <-- No longer required since we are only logging one activity

                    //Log
                    PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_Sleeping,
                                                   "Scheduled tasks complete. Sleeping for " + Sahara.Core.Settings.Platform.Custodian.Frequency.Description,
                                                   "Tasks completed in " + stopwatch.ElapsedMilliseconds.ToString("#,##0") + " milliseconds");

                    // PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_NextRun,
                    //"Custodian next run in " + Sahara.Core.Settings.Platform.Custodian.Frequency.Description,
                    //DateTime.UtcNow.AddMilliseconds(Sahara.Core.Settings.Platform.Custodian.Frequency.Length).ToString()
                    //);

                    #endregion
                }
                else
                {
                    //Check if platform is initialized again
                    platformInitialized = PlatformInitializationManager.isPlatformInitialized();
                }

                //Sleep
                Thread.Sleep(Sahara.Core.Settings.Platform.Custodian.Frequency.Length);
            }
        }
        public AuthenticationResponse Authenticate(string email, string password, string ipAddress, string origin, string sharedClientKey)
        {
            // Ensure the clients are certified.
            if (sharedClientKey != Sahara.Core.Platform.Requests.RequestManager.SharedClientKey)
            {
                return(null);
            }

            var authResponse = new AuthenticationResponse();

            //From here you may log the fact that the user has authenticated at this time (if this is something you wish to track)
            //login.IP; <-- IP address for logging purposes

            var result = PlatformSecurityManager.AuthenticateUser(email, password);

            authResponse.isSuccess    = result.isSuccess;
            authResponse.ErrorMessage = result.ErrorMessage;

            if (result.isSuccess)
            {
                //Get the IdentityUser from the ResponseObject:
                var platformUserIdentity = (PlatformUserIdentity)result.ResponseObject;


                //Convert to non Identity version & add to response object:
                authResponse.PlatformUser = PlatformUserManager.TransformPlatformUserIdentityToPlatformUser(platformUserIdentity);

                //Get Claims based identity for the user
                System.Security.Claims.ClaimsIdentity identity = PlatformUserManager.GetUserClaimsIdentity(
                    platformUserIdentity,
                    DefaultAuthenticationTypes.ApplicationCookie); //<-- Uses a cookie for the local web application

                // You can add to claims thusly:
                //identity.AddClaim(new Claim(ClaimTypes.Name, "Name"));

                authResponse.ClaimsIdentity = identity;

                #region Log Platform user Activity (AuthenticationPassed)

                try
                {
                    PlatformLogManager.LogActivity(
                        CategoryType.Authentication,
                        ActivityType.Authentication_Passed,
                        "Successfull log in.",
                        authResponse.PlatformUser.FirstName + " successfully logged in.",
                        null,
                        null,
                        authResponse.PlatformUser.Id,
                        authResponse.PlatformUser.FirstName,
                        authResponse.PlatformUser.Email,
                        ipAddress,
                        origin);
                }
                catch { }

                #endregion
            }
            else
            {
                #region Log Platform User Activity (AuthenticationFailed)

                try
                {
                    PlatformLogManager.LogActivity(
                        CategoryType.Authentication,
                        ActivityType.Authentication_Failed,
                        "An attempt to log into the platform admin with email '" + email + "' has failed.",
                        result.ErrorMessage,
                        null,
                        null,
                        "Unknown",
                        "Unknown",
                        email,
                        ipAddress,
                        origin);
                }
                catch { }

                #endregion
            }

            return(authResponse);
        }
        public static DataAccessResponseType ProcessSendApplicationDataInjectionImageDocuments(string accountId, int documentInjectionCount)
        {
            var result = new DataAccessResponseType {
                isSuccess = false
            };

            //Get the account
            var account = AccountManager.GetAccount(accountId);

            //Create base document
            var imageDocument = new ApplicationImageDocumentModel
            {
                AccountID    = accountId,
                DocumentType = "ApplicationImage",
                Title        = "Generic Application Image Document",
                Description  = "Generic description for batch injected document. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
            };

            //Get the DocumentDB Client
            //var client = Sahara.Core.Settings.Azure.DocumentDB.DocumentClients.AccountDocumentClient;
            //var dbSelfLink = Sahara.Core.Settings.Azure.DocumentDB.AccountPartitionDatabaseSelfLink;
            //Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.OpenAsync();

            //Build a collection Uri out of the known IDs
            //(These helpers allow you to properly generate the following URI format for Document DB:
            //"dbs/{xxx}/colls/{xxx}/docs/{xxx}"
            Uri collectionUri = UriFactory.CreateDocumentCollectionUri(Sahara.Core.Settings.Azure.DocumentDB.AccountPartitionDatabaseId, account.DocumentPartition);

            string triggerId      = "IncrementApplicationImageCount";
            var    requestOptions = new RequestOptions {
                PostTriggerInclude = new List <string> {
                    triggerId
                }
            };

            int documentsInjected = 0;
            //int retryAttempts = 0;
            //int maxAttemptsPerRetry = 0;  //<-- Used to track max retries per attempt

            // Create new stopwatch
            Stopwatch stopwatch = new Stopwatch();

            // Begin timing tasks
            stopwatch.Start();

            //var retryStrategy = new DocumentDbRetryStrategy{ FastFirstRetry = true };

            //DocumentDbRetryStrategy.F

            do
            {
                imageDocument.Id = Guid.NewGuid().ToString();

                var createDocumentResponse = Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.CreateDocumentAsync(collectionUri.ToString(), imageDocument, requestOptions).Result;
                documentsInjected++; //<--Increment amount of documents that have been injected

                try
                {
                    AccountCapacityManager.InvalidateAccountCapacitiesCache(accountId); //<--Invalidate Account Capacities Cache
                }
                catch { }
            }while (documentsInjected != documentInjectionCount);


            if (documentsInjected == documentInjectionCount)
            {
                result.isSuccess = true;
            }

            stopwatch.Stop();
            //Output timing into data injection log
            PlatformLogManager.LogActivity(
                CategoryType.DataInjection,
                ActivityType.DataInjection_ImageDocuments,
                "Batch Injection complete! " + documentsInjected + " of " + documentInjectionCount + " documents injected",
                "Time: " + stopwatch.ElapsedMilliseconds + " Milliseconds( " + String.Format("{0:0,0.00}", TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds).TotalMinutes) + " Minutes)",     // | Retries: " + retryAttempts + " | Max Attempts Per Retry: " + maxAttemptsPerRetry,
                accountId
                );

            return(result);
        }
        /// <summary>
        /// Deletes all image records for an object in table storage
        /// </summary>
        /// <param name="accountId"></param>
        /// <param name="imageGroupTypeNameKey"></param>
        /// <param name="objectId"></param>
        /// <returns></returns>
        internal static DataAccessResponseType DeleteAllImageRecordsForObject(string accountId, string storagePartition, string imageFormatGroupTypeNameKey, string objectId)
        {
            var response = new DataAccessResponseType();

            //CloudTableClient cloudTableClient = Sahara.Core.Settings.Azure.Storage.StorageConnections.AccountsStorage.CreateCloudTableClient();
            CloudTableClient cloudTableClient = Settings.Azure.Storage.GetStoragePartitionAccount(storagePartition).CreateCloudTableClient();

            //Create and set retry policy
            //IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(1), 4);
            IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 4);

            cloudTableClient.DefaultRequestOptions.RetryPolicy = linearRetryPolicy;



            try
            {
                //Delete From MAIN table
                CloudTable cloudTable1 = cloudTableClient.GetTableReference(Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(accountId) + ImageRecordTableName(imageFormatGroupTypeNameKey));
                //cloudTable1.CreateIfNotExists();
                List <TableEntity> productImageEntities1 = cloudTable1.CreateQuery <TableEntity>().Where(p => p.PartitionKey == objectId).ToList();

                foreach (TableEntity productImageEntity in productImageEntities1)
                {
                    cloudTable1.Execute(TableOperation.Delete(productImageEntity));
                }

                //Delete From LISTING table
                CloudTable cloudTable2 = cloudTableClient.GetTableReference(Sahara.Core.Common.Methods.SchemaNames.AccountIdToTableStorageName(accountId) + ImageRecordListingTableName(imageFormatGroupTypeNameKey));
                //cloudTable2.CreateIfNotExists();
                List <TableEntity> productImageEntities2 = cloudTable2.CreateQuery <TableEntity>().Where(p => p.PartitionKey == objectId).ToList();

                foreach (TableEntity productImageEntity in productImageEntities2)
                {
                    cloudTable2.Execute(TableOperation.Delete(productImageEntity));
                }

                response.isSuccess = true;
            }
            catch (Exception e)
            {
                if (!e.Message.Contains("(404) Not Found"))
                {
                    PlatformLogManager.LogActivity(
                        CategoryType.Error,
                        ActivityType.Error_Exception,
                        e.Message,
                        "Exception while attempting to delete all image records for " + imageFormatGroupTypeNameKey + " '" + objectId + "' in table storage",
                        accountId,
                        null,
                        null,
                        null,
                        null,
                        null,
                        System.Reflection.MethodBase.GetCurrentMethod().ToString(),
                        null
                        );
                }
            }

            return(response);
        }
예제 #27
0
        public static DataAccessResponseType ProvisionAccount(Account account)
        {
            var response = new DataAccessResponseType();

            #region Pre Provisioning Verification

            bool _documentPartitioning = true;        //<-- If false will skip provisioning DocumentDB resources for accounts
            bool _searchPartitioning   = true;        //<-- If false will skip provisioning Search resources for accounts
            bool _storagePartitioning  = true;        //<-- If false will skip provisioning Search resources for accounts
            bool _sqlPartitioning      = true;        //<-- If false will skip provisioning a SQL Location and SchemeName for accounts

            StoragePartition storagePartition = null; //<-- Chosen partition for this account
            SearchPartition  searchPartition  = null; //<-- Chosen partition for this account

            //Make sure account isn't already provisioned
            if (account.Provisioned)
            {
                response.isSuccess    = false;
                response.ErrorMessage = "Account is already provisioned!";

                return(response);
            }
            if (account.StripeSubscriptionID == null || account.StripeCustomerID == null)
            {
                response.isSuccess    = false;
                response.ErrorMessage = "This account has not been assigned a payment plan or a Stripe CustomerID";

                return(response);
            }

            //If Account object is passed in without users get all/initial user(s):
            if (account.Users == null)
            {
                account.Users = AccountUserManager.GetUsers(account.AccountID.ToString());
            }

            #region Ensure that there is a storage partition available and select next available spot

            if (_storagePartitioning)
            {
                var storagePartitions = StoragePartitioningManager.GetStoragePartitions();


                //Sort with lowest tenant count at the top:
                storagePartitions = storagePartitions.OrderBy(o => o.TenantCount).ToList();

                if (storagePartitions.Count > 0)
                {
                    if (storagePartitions[0].TenantCount >= Settings.Platform.Partitioning.MaximumTenantsPerStorageAccount)
                    {
                        response.isSuccess    = false;
                        response.ErrorMessage = "There are no storage partitions available for this account! Please create one before attempting to provision.";

                        //Reset account to inactive so you can restart partitioning sequence after partition hopper has additional partitions added
                        AccountManager.UpdateAccountActiveState(account.AccountID.ToString(), false);

                        return(response);
                    }
                    else
                    {
                        //Assign storage partition:
                        storagePartition = storagePartitions[0];
                    }
                }
                else
                {
                    response.isSuccess    = false;
                    response.ErrorMessage = "There are no storage partitions available on this platform! Cannot provision any accounts!";

                    //Reset account to inactive so you can restart partitioning sequence after partition hopper has additional partitions added
                    AccountManager.UpdateAccountActiveState(account.AccountID.ToString(), false);

                    return(response);
                }
            }



            #endregion

            #region Ensure that there is a search partition available and select next available spot

            if (_searchPartitioning)
            {
                //Get search plan type for this plan tier
                string searchPlan = account.PaymentPlan.SearchPlan;

                //Get list of search partitions available with this plan type
                var searchPartitions = SearchPartitioningManager.GetSearchPartitions(searchPlan);

                int maxTenantsAllowed = Int32.Parse((searchPlan.Substring(searchPlan.LastIndexOf("-") + 1)));

                /* MAx Tenatnts are now pulled from the SarchPlan name
                 *
                 * int maxTenantsAllowed = 0;
                 *
                 * if(searchPlan == "Basic")
                 * {
                 *  maxTenantsAllowed = Settings.Platform.Partitioning.MaximumTenantsPerBasicSearchServiceShared;
                 * }
                 * else if (searchPlan == "Basic-Dedicated")
                 * {
                 *  maxTenantsAllowed = Settings.Platform.Partitioning.MaximumTenantsPerBasicSearchServiceDedicated;
                 * }
                 * else if(searchPlan == "S1")
                 * {
                 *  maxTenantsAllowed = Settings.Platform.Partitioning.MaximumTenantsPerS1SearchServiceShared;
                 * }
                 * else if (searchPlan == "S1-Dedicated")
                 * {
                 *  maxTenantsAllowed = Settings.Platform.Partitioning.MaximumTenantsPerS1SearchServiceDedicated;
                 * }
                 * else if (searchPlan == "S2")
                 * {
                 *  maxTenantsAllowed = Settings.Platform.Partitioning.MaximumTenantsPerS2SearchServiceShared;
                 * }
                 * else if (searchPlan == "S2-Dedicated")
                 * {
                 *  maxTenantsAllowed = Settings.Platform.Partitioning.MaximumTenantsPerS2SearchServiceDedicated;
                 * }
                 * else if(searchPlan == "Free")
                 * {
                 *  maxTenantsAllowed = Settings.Platform.Partitioning.MaximumTenantsPerFreeSearchService;
                 * }
                 */

                //Sort with lowest tenant count at the top:
                searchPartitions = searchPartitions.OrderBy(o => o.TenantCount).ToList();

                if (searchPartitions.Count > 0)
                {
                    if (searchPartitions[0].TenantCount >= maxTenantsAllowed)
                    {
                        response.isSuccess    = false;
                        response.ErrorMessage = "There are no '" + searchPlan + "' search partitions available for this account! Please create one before attempting to provision.";

                        //Reset account to inactive so you can restart partitioning sequence after partition hopper has additional partitions added
                        AccountManager.UpdateAccountActiveState(account.AccountID.ToString(), false);

                        return(response);
                    }
                    else
                    {
                        //Assign storage partition:
                        searchPartition = searchPartitions[0];
                    }
                }
                else
                {
                    response.isSuccess    = false;
                    response.ErrorMessage = "There are no '" + searchPlan + "' search partitions available on this platform! Cannot provision any accounts!";

                    //Reset account to inactive so you can restart partitioning sequence after partition hopper has additional partitions added
                    AccountManager.UpdateAccountActiveState(account.AccountID.ToString(), false);

                    return(response);
                }
            }



            #endregion

            #endregion

            #region Account Partitioning

            #region Document Database Partitioning (REMOVED)

            if (_documentPartitioning)
            {
                //Connect to the document client & get the database selfLink
                //var client = Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient;

                //Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.OpenAsync().ConfigureAwait(false);
                //Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.OpenAsync();

                //var dataBaseSelfLink = Sahara.Core.Settings.Azure.DocumentDB.AccountPartitionDatabaseSelfLink;

                //STEP 1: Get or create the next available document partition for the 'Free' tier
                var partitioningResult = DocumentPartitioningManager.CreateDocumentCollectionAccountPartition(account.AccountNameKey, Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient, Sahara.Core.Settings.Azure.DocumentDB.AccountPartitionDatabaseId);

                if (partitioningResult.isSuccess == true)
                {
                    DocumentCollection nextAvailablePartitionCollection = (DocumentCollection)partitioningResult.ResponseObject;

                    #region STEP 4: Add Account Settings Document for this account on the collection

                    var       accountSettingsDocumentCreated = false;
                    Exception accountSettingsException       = null;

                    try
                    {
                        var accountSettingsDocument = new AccountSettingsDocumentModel {
                            Id = "AccountSettings"
                        };

                        accountSettingsDocument.ContactSettings             = new ContactSettingsModel();
                        accountSettingsDocument.ContactSettings.ContactInfo = new ContactInfoModel();
                        accountSettingsDocument.SalesSettings = new SalesSettingsModel();

                        //Default LeadLabels
                        accountSettingsDocument.SalesSettings.LeadLabels = new List <string>();
                        accountSettingsDocument.SalesSettings.LeadLabels.Add("New");
                        accountSettingsDocument.SalesSettings.LeadLabels.Add("Archive");
                        accountSettingsDocument.SalesSettings.LeadLabels.Add("Deleted");

                        accountSettingsDocument.Theme = "Light";                                   //<-- Default Theme
                        accountSettingsDocument.SalesSettings.ButtonCopy      = "I'm interested!"; //<-- Default Theme
                        accountSettingsDocument.SalesSettings.DescriptionCopy = "Fill out our contact form and a member of our team will contact you directly.";



                        Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.CreateDocumentAsync(nextAvailablePartitionCollection.SelfLink, accountSettingsDocument).ConfigureAwait(false);

                        accountSettingsDocumentCreated = true;
                    }
                    #region Manage Exception & Create Manual Instructions

                    catch (DocumentClientException de)
                    {
                        accountSettingsException = de.GetBaseException();
                    }
                    catch (Exception e)
                    {
                        accountSettingsException = e;
                    }

                    if (!accountSettingsDocumentCreated)
                    {
                        #region Log Exception

                        if (accountSettingsException != null)
                        {
                            PlatformExceptionsHelper.LogExceptionAndAlertAdmins(
                                accountSettingsException,
                                "creating an account settings document into a partition during account provisioning",
                                System.Reflection.MethodBase.GetCurrentMethod(),
                                account.AccountID.ToString(),
                                account.AccountName
                                );
                        }


                        #endregion

                        #region Manual Instructions

                        //Not successfull, All tasks within 'GetNextAvailableDocumentPartition' must be run manually
                        PlatformLogManager.LogActivity(
                            CategoryType.ManualTask,
                            ActivityType.ManualTask_DocumentDB,
                            "AccountSettingsDocumentModel file creation failed during account provisioning",
                            "Please create the 'AccountSettingsDocumentModel' document for '" + account.AccountName + "' within the '" + nextAvailablePartitionCollection.Id + "' collection manually.",
                            account.AccountID.ToString(),
                            account.AccountName,
                            null,
                            null,
                            null,
                            null,
                            System.Reflection.MethodBase.GetCurrentMethod().ToString()
                            );

                        #endregion
                    }

                    #endregion

                    #endregion
                }
                else
                {
                    #region Manual Instructions

                    //Not successfull, All tasks within 'GetNextAvailableDocumentPartition' must be run manually
                    PlatformLogManager.LogActivity(
                        CategoryType.ManualTask,
                        ActivityType.ManualTask_Other,
                        "Document partitioning failed during account provisioning",
                        "Please run all tasks under 'DocumentPartitioningManager.GetNextAvailableDocumentPartition('Free', client, dataBaseSelfLink)' as Well as 'if (partitioningResult.isSuccess == true)' manually. This may include creating a new DocumentPartition, updating account DocumentPartitionId and creating an AccountPropertiesDocument for this account into the new partition.",
                        account.AccountID.ToString(),
                        account.AccountName,
                        null,
                        null,
                        null,
                        null,
                        System.Reflection.MethodBase.GetCurrentMethod().ToString()
                        );

                    #endregion
                }

                #region Depricated DocumentDB Code

                /*
                 * try
                 * {
                 *  DocumentClient client = Sahara.Core.Settings.Azure.DocumentDB.DocumentClients.AccountDocumentClient;
                 *  client.OpenAsync(); //<-- By default, the first request will have a higher latency because it has to fetch the address routing table. In order to avoid this startup latency on the first request, you should call OpenAsync() once during initialization as follows.
                 *
                 *
                 *  //Generate Account Database
                 *  Database accountDatabase = client.CreateDatabaseAsync(new Database { Id = account.AccountID.ToString() }).Result;
                 *
                 *
                 *  //Generate "AccountProperties" Collection on the database
                 *  DocumentCollection accountPropertiesCollection = client.CreateDocumentCollectionAsync(accountDatabase.SelfLink, new DocumentCollection { Id = "AccountProperties" }).Result;
                 *
                 *
                 *  //Generate "SelfLinkReferences" Document within AccountProperties" collection
                 *  Document selfLinkReferencesDocument = client.CreateDocumentAsync(accountPropertiesCollection.SelfLink, new SelfLinkReferencesDocumentModel { Id = "SelfLinkReferences" }).Result;
                 *
                 *
                 *  //Store all the SelfLinks
                 *  var documentUpdateResults = Sql.Statements.UpdateStatements.UpdateDocumentDatabaseLinks(account.AccountID.ToString(), accountDatabase.SelfLink, accountPropertiesCollection.SelfLink, selfLinkReferencesDocument.SelfLink);
                 *  if (documentUpdateResults)
                 *  {
                 *
                 *  }
                 *  else
                 *  {
                 *
                 *      var errorMessage = "DocumentDB Selflink insertion into the '" + account.AccountName + "' account has failed";
                 *      var errorDetails = "AccountID: '" + account.AccountID + "' Error: 'DocumentDB resources have been provisioned, but an error occured when updating database columns for the account'";
                 *
                 *      //Log Errors
                 *      PlatformLogManager.LogActivity(
                 *              CategoryType.Error,
                 *              ActivityType.Error_Other,
                 *              errorMessage,
                 *              errorDetails,
                 *              account.AccountID.ToString(),
                 *              account.AccountName
                 *          );
                 *
                 *      return new DataAccessResponseType { isSuccess = false, ErrorMessage = errorMessage };
                 *  }
                 * }
                 * catch (Exception e)
                 * {
                 #region Handle Exception
                 *
                 *  //Log exception and email platform admins
                 *  PlatformExceptionsHelper.LogExceptionAndAlertAdmins(
                 *      e,
                 *      "attempting to partition DocumentDB resources for the '" + account.AccountName + "' account during provisioning.",
                 *      System.Reflection.MethodBase.GetCurrentMethod(),
                 *      account.AccountID.ToString(),
                 *      account.AccountName
                 *  );
                 *
                 #endregion
                 * }
                 */

                #endregion
            }

            #endregion

            #region Storage Partitioning

            if (_storagePartitioning)
            {
                /* No longer need to set anything up (Back to document db)
                 *
                 * //Create setings JSON doc in storage (DocumentDB is now OFF)
                 * var accountSettingsDocument = new AccountSettingsDocumentModel { Id = "AccountSettings" };
                 *
                 * accountSettingsDocument.ContactSettings = new ContactSettingsModel();
                 * accountSettingsDocument.ContactSettings.ContactInfo = new ContactInfoModel();
                 * accountSettingsDocument.SalesSettings = new SalesSettingsModel();
                 *
                 * //Default LeadLabels
                 * accountSettingsDocument.SalesSettings.LeadLabels = new List<string>();
                 * accountSettingsDocument.SalesSettings.LeadLabels.Add("New");
                 * accountSettingsDocument.SalesSettings.LeadLabels.Add("Archive");
                 * accountSettingsDocument.SalesSettings.LeadLabels.Add("Deleted");
                 *
                 * accountSettingsDocument.Theme = "Light"; //<-- Default Theme
                 * accountSettingsDocument.SalesSettings.ButtonCopy = "I'm interested!"; //<-- Default Theme
                 * accountSettingsDocument.SalesSettings.DescriptionCopy = "Fill out our contact form and a member of our team will contact you directly.";
                 *
                 * //Save to designated storage account
                 * CloudStorageAccount storageAccount;
                 * StorageCredentials storageCredentials = new StorageCredentials(storagePartition.Name, storagePartition.Key);
                 * storageAccount = new CloudStorageAccount(storageCredentials, false);
                 * CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
                 *
                 * //Create and set retry policy
                 * IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromMilliseconds(400), 6);
                 * blobClient.DefaultRequestOptions.RetryPolicy = exponentialRetryPolicy;
                 *
                 * //Creat/Connect to the Blob Container for this account
                 * blobClient.GetContainerReference(account.AccountNameKey).CreateIfNotExists(BlobContainerPublicAccessType.Blob); //<-- Create and make public
                 *
                 *
                 * CloudBlobContainer blobContainer = blobClient.GetContainerReference(account.AccountNameKey);
                 *
                 * //Get reference to the text blob or create if not exists.
                 * CloudBlockBlob blockBlob = blobContainer.GetBlockBlobReference("settings/" + "accountSettings.json");
                 *
                 * blockBlob.UploadText(JsonConvert.SerializeObject(accountSettingsDocument));
                 *
                 * //Save to storage
                 * //Convert final BMP to byteArray
                 * //Byte[] finalByteArray;
                 *
                 * //finalByteArray = outStream.ToArray();
                 *
                 * //blockBlob.UploadFromByteArray(finalByteArray, 0, finalByteArray.Length);
                 *
                 */
            }

            #endregion

            #region SQL Partitioning

            if (_sqlPartitioning)
            {
                try
                {
                    // 1. Get and assign the next available database partition for this account to be provisioned into:
                    var getAndAssignPartitionResponse = SqlPartitioningManager.GetAndAssignNextAvailableAccountSqlPartition(account.AccountID.ToString());

                    if (getAndAssignPartitionResponse.isSuccess)
                    {
                        string DatabasePartitionName = getAndAssignPartitionResponse.SuccessMessage;

                        // 2. Run creation scripts to provision accounts schema to the selected partition:
                        var generateAccountSchemaResponse = AccountProvisioning.GenerateAccountSchema(account.AccountID.ToString(), DatabasePartitionName);

                        if (generateAccountSchemaResponse.isSuccess)
                        {
                            generateAccountSchemaResponse.SuccessMessage = DatabasePartitionName; //<-- Return the name of the database partition name
                        }
                        else
                        {
                            return(generateAccountSchemaResponse);
                        }
                    }
                    else
                    {
                        return(getAndAssignPartitionResponse);
                    }
                }
                catch (Exception e)
                {
                    #region Handle Exception

                    //Log exception and email platform admins
                    PlatformExceptionsHelper.LogExceptionAndAlertAdmins(
                        e,
                        "attempting to partition SQL for the '" + account.AccountName + "' account during provisioning.",
                        System.Reflection.MethodBase.GetCurrentMethod(),
                        account.AccountID.ToString(),
                        account.AccountName
                        );

                    #endregion
                }
            }



            #endregion

            #region Search Partitioning

            if (_searchPartitioning)
            {
                //Create an Product Search Index for this account on the selected search partition ---------------------
                var searchIndexCreated = ProductSearchManager.CreateProductSearchIndex(account.AccountNameKey, searchPartition.Name, searchPartition.Key);
            }

            #endregion

            #endregion

            #region Post Partitioning Tasks

            // 1. Mark the Account as Provisioned, Active and assign a ProvisioningDate:
            var result = Sql.Statements.UpdateStatements.UpdateProvisiongStatus(account.AccountID.ToString(), true, true, storagePartition.Name, searchPartition.Name);


            if (result)
            {
                // 1. Create a platform user account SO we can log into the account for management purposes:
                AccountUserManager.CreateAccountUser(account.AccountID.ToString(), "platformadmin@[Config_PlatformEmail]", "Platform", "Admin", "[Config_PlatformPassword_AzureKeyVault]", Settings.Accounts.Users.Authorization.Roles.PlatformAdmin, true, null, true);

                // 2. Invalidated/Update the cache for this account
                AccountManager.UpdateAccountDetailCache(account.AccountNameKey);

                // 3. Email the creator with sucessful provisioning message and login info:

                /*
                 * EmailManager.Send(
                 *      account.Users[0].Email, //<-- Will only have the initial user
                 *      Settings.Endpoints.Emails.FromProvisioning,
                 *      Settings.Copy.EmailMessages.ProvisioningComplete.FromName,
                 *      Settings.Copy.EmailMessages.ProvisioningComplete.Subject,
                 *      String.Format(Settings.Copy.EmailMessages.ProvisioningComplete.Body, account.AccountNameKey),
                 *      true
                 *  );*/

                // 4. Send an alert to the platform admin(s):
                EmailManager.Send(
                    Settings.Endpoints.Emails.PlatformEmailAddresses,
                    Settings.Endpoints.Emails.FromProvisioning,
                    "Provisioning " + Settings.Application.Name,
                    "Account Provisioned",
                    "<b>'" + account.AccountName + "'</b> has just been provisioned.",
                    true
                    );

                // 5. Log Successfull Provisioning Activity
                PlatformLogManager.LogActivity(CategoryType.Account,
                                               ActivityType.Account_Provisioned,
                                               "Provisioning of '" + account.AccountName + "' has completed",
                                               "AccountID: '" + account.AccountID + "'",
                                               account.AccountID.ToString(), account.AccountName);

                //Register subdomains
                try
                {
                    var cloudFlareResult = CloudFlareManager.RegisterSubdomains(account.AccountNameKey);

                    if (cloudFlareResult.isSuccess == false)
                    {
                        //Log exception and email platform admins
                        PlatformExceptionsHelper.LogErrorAndAlertAdmins(
                            cloudFlareResult.ErrorMessage,
                            "attempting to add cloudflare subdomains for the '" + account.AccountName + "' account during provisioning.",
                            System.Reflection.MethodBase.GetCurrentMethod(),
                            account.AccountID.ToString(),
                            account.AccountName
                            );
                    }
                }
                catch (Exception e)
                {
                    //Log exception and email platform admins
                    PlatformExceptionsHelper.LogExceptionAndAlertAdmins(
                        e,
                        "attempting to register cloudflare subdomains for the '" + account.AccountName + "' account during provisioning.",
                        System.Reflection.MethodBase.GetCurrentMethod(),
                        account.AccountID.ToString(),
                        account.AccountName
                        );
                }

                return(new DataAccessResponseType {
                    isSuccess = true
                });
            }
            else
            {
                var errorMessage = "Account has been fully provisioned, but an error occured when setting the Account table to Active and assigning a provisioning date";

                PlatformLogManager.LogActivity(CategoryType.Error,
                                               ActivityType.Error_Other,
                                               "Provisioning of '" + account.AccountName + "' has failed",
                                               errorMessage,
                                               account.AccountID.ToString(), account.AccountName);

                return(new DataAccessResponseType {
                    isSuccess = false, ErrorMessage = errorMessage
                });
            }



            #endregion
        }
예제 #28
0
        // Future performance update: have client upload image to intermediary storage, submit location with imag eid for WCF processing (similar to other imageing solutions)
        public DataAccessResponseType UpdatePlatformUserProfilePhoto(string userId, byte[] imageByteArray, string requesterId, RequesterType requesterType, string sharedClientKey)
        {
            // Ensure the clients are certified.
            if (sharedClientKey != Sahara.Core.Platform.Requests.RequestManager.SharedClientKey)
            {
                return(null);
            }

            #region Validate Request

            var requesterName  = string.Empty;
            var requesterEmail = string.Empty;

            var requestResponseType = RequestManager.ValidateRequest(requesterId,
                                                                     requesterType, out requesterName, out requesterEmail,
                                                                     Sahara.Core.Settings.Platform.Users.Authorization.Roles.SuperAdmin,
                                                                     null);

            if (!requestResponseType.isApproved)
            {
                //Request is not approved, send results:
                return(new DataAccessResponseType {
                    isSuccess = false, ErrorMessage = requestResponseType.requestMessage
                });
            }

            #endregion


            var result = PlatformUserManager.UpdateProfilePhoto(userId, imageByteArray);

            #region Log Platoform Activity

            if (result.isSuccess)
            {
                try
                {
                    var logDescription = string.Empty;

                    if (userId == requesterId)
                    {
                        logDescription = requesterName + " has updated their profile photo";
                    }
                    else
                    {
                        var user = PlatformUserManager.GetUser(userId);
                        logDescription = requesterName + " updated " + user.FullName + "'s profile photo";
                    }

                    PlatformLogManager.LogActivity(
                        CategoryType.PlatformUser,
                        ActivityType.PlatformUser_Edited,
                        "Photo updated",
                        logDescription,
                        null,
                        null,
                        requesterId,
                        requesterName,
                        requesterEmail
                        );
                }
                catch { }
            }

            #endregion

            return(result);
        }
예제 #29
0
        public static DataAccessResponseType CacheAccountData()
        {
            //Set up security channel to allow for SSL/TLS
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            ServicePointManager.ServerCertificateValidationCallback = delegate { return(true); };


            var response = new DataAccessResponseType();


            var accounts = AccountManager.GetAllAccountsByFilter("Provisioned", "1", 0, 2000, "AccountNameKey");

            //Loop through each account and call public api to preload data
            foreach (var account in accounts)
            {
                #region Account Info

                try
                {
                    string callName = "account";
                    string url      = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountServiceDomain + "/account";

                    HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;

                    //optional
                    HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse;

                    try
                    {
                        Stream stream = webRequestResponse.GetResponseStream();
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshCache_Status, "Refreshing " + callName + " api cache for '" + account.AccountName + "' at:" + url);
                    }
                    catch (Exception e)
                    {
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " api cache for '" + account.AccountName + "': " + e.Message);
                    }
                }
                catch (Exception e)
                {
                    PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing account api cache for '" + account.AccountName + ": " + e.Message);
                }

                #endregion

                #region Category Tree

                try
                {
                    string callName = "categories";
                    string url      = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountServiceDomain + "/categories/tree?includeImages=true";

                    HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;

                    //optional
                    HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse;

                    try
                    {
                        Stream stream = webRequestResponse.GetResponseStream();
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshCache_Status, "Refreshing " + callName + " api cache for '" + account.AccountName + "' at:" + url);
                    }
                    catch (Exception e)
                    {
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " api cache for '" + account.AccountName + "': " + e.Message);
                    }
                }
                catch (Exception e)
                {
                    PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing categories api cache for '" + account.AccountName + ": " + e.Message);
                }

                #endregion

                #region Search Query

                try
                {
                    string callName = "search";
                    string url      = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountServiceDomain + "/search/products?query=test?skip=0&take=2";

                    HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;

                    //optional
                    HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse;

                    try
                    {
                        Stream stream = webRequestResponse.GetResponseStream();
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshCache_Status, "Refreshing " + callName + " api cache for '" + account.AccountName + "' at:" + url);
                    }
                    catch (Exception e)
                    {
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " api cache for '" + account.AccountName + "': " + e.Message);
                    }
                }
                catch (Exception e)
                {
                    PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing search api cache for '" + account.AccountName + ": " + e.Message);
                }

                #endregion

                #region Search Sortables

                try
                {
                    string callName = "search-sortables";
                    string url      = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountServiceDomain + "/search/sortables";

                    HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;

                    //optional
                    HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse;

                    try
                    {
                        Stream stream = webRequestResponse.GetResponseStream();
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshCache_Status, "Refreshing " + callName + " api cache for '" + account.AccountName + "' at:" + url);
                    }
                    catch (Exception e)
                    {
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " api cache for '" + account.AccountName + "': " + e.Message);
                    }
                }
                catch (Exception e)
                {
                    PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing search-sortables api cache for '" + account.AccountName + ": " + e.Message);
                }

                #endregion

                #region Search Facets

                try
                {
                    string callName = "search-facets";
                    string url      = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountServiceDomain + "/search/facets";

                    HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;

                    //optional
                    HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse;

                    try
                    {
                        Stream stream = webRequestResponse.GetResponseStream();
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshCache_Status, "Refreshing " + callName + " api cache for '" + account.AccountName + "' at:" + url);
                    }
                    catch (Exception e)
                    {
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " api cache for '" + account.AccountName + "': " + e.Message);
                    }
                }
                catch (Exception e)
                {
                    PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing search-facets api cache for '" + account.AccountName + ": " + e.Message);
                }

                #endregion

                #region Properties

                try
                {
                    string callName = "properties";
                    string url      = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountServiceDomain + "/properties/product";

                    HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;

                    //optional
                    HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse;

                    try
                    {
                        Stream stream = webRequestResponse.GetResponseStream();
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshCache_Status, "Refreshing " + callName + " api cache for '" + account.AccountName + "' at:" + url);
                    }
                    catch (Exception e)
                    {
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " api cache for '" + account.AccountName + "': " + e.Message);
                    }
                }
                catch (Exception e)
                {
                    PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing properties api cache for '" + account.AccountName + ": " + e.Message);
                }

                #endregion

                #region Tags

                try
                {
                    string callName = "tags";
                    string url      = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountServiceDomain + "/tags";

                    HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;

                    //optional
                    HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse;

                    try
                    {
                        Stream stream = webRequestResponse.GetResponseStream();
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshCache_Status, "Refreshing " + callName + " api cache for '" + account.AccountName + "' at:" + url);
                    }
                    catch (Exception e)
                    {
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " api cache for '" + account.AccountName + "': " + e.Message);
                    }
                }
                catch (Exception e)
                {
                    PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing tags api cache for '" + account.AccountName + ": " + e.Message);
                }

                #endregion
            }

            //Loop through each account and call public site to preload pages
            foreach (var account in accounts)
            {
                #region Public Site Search

                try
                {
                    string callName = "account-search";
                    string url      = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountSiteDomain + "/search";

                    HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;

                    //optional
                    HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse;

                    try
                    {
                        Stream stream = webRequestResponse.GetResponseStream();
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshAccountSite_Status, "Refreshing " + callName + " site cache for '" + account.AccountName + "' at:" + url);
                    }
                    catch (Exception e)
                    {
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " site cache for '" + account.AccountName + "': " + e.Message);
                    }
                }
                catch (Exception e)
                {
                    PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing account-search site cache for '" + account.AccountName + ": " + e.Message);
                }

                #endregion


                #region Public Site Search

                try
                {
                    string callName = "account-home";
                    string url      = "https://" + account.AccountNameKey + "." + Settings.Endpoints.URLs.AccountSiteDomain;

                    HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;

                    //optional
                    HttpWebResponse webRequestResponse = webRequest.GetResponse() as HttpWebResponse;

                    try
                    {
                        Stream stream = webRequestResponse.GetResponseStream();
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Custodian_RefreshAccountSite_Status, "Refreshing " + callName + " site cache for '" + account.AccountName + "' at:" + url);
                    }
                    catch (Exception e)
                    {
                        PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing " + callName + " site cache for '" + account.AccountName + "': " + e.Message);
                    }
                }
                catch (Exception e)
                {
                    PlatformLogManager.LogActivity(CategoryType.Custodian, ActivityType.Error_Custodian, "Error refreshing account-home site cache for '" + account.AccountName + ": " + e.Message);
                }

                #endregion
            }


            response.isSuccess = true;
            //response.ErrorMessage = "Not implemented.";

            return(response);
        }
        public static DataAccessResponseType RegisterNewAccount(RegisterNewAccountModel model)
        {
            //trim the name of whitespaces (start & end):
            model.AccountName = model.AccountName.Trim();

            #region Refactoring notes

            /*
             *
             *  With some refactoring you can start them directly with a chosen payment plan by passing a planid parameter to the Registration site (and ultimatly into this method) along with C.C. info
             *
             *  This method will then check for a MonthlyRate > 0 and attempt to process the C.C.
             *  note: You would only add a Credit Card capture form to the Registration site if a plan with a MonthlyRate above 0 is selected -->
             *
             *
             *
             *  -- Adding a new "AllowRegistration" bool to the PaymentPlan object will allow for validation of selected plans coming in from users on this method for scenarios where users can choose a plan while signing up to avoid passing in ID's for plans such as "Unlimited" which must be approved by a Platform Admin
             *
             */

            #endregion

            var response = new DataAccessResponseType {
                isSuccess = true
            };

            try
            {
                #region Validate Account Info
                //Validate Registration Data:

                #region Refactoring notes

                /*
                 *
                 *
                 *  -- Adding a new "AllowRegistration" bool to the PaymentPlan object will allow for validation of selected plans coming in from users on AccountRegistrationManager for scenarios where users can choose a plan while signing up to avoid passing in ID's for plans such as "Unlimited" which must be approved by a Platform Admin
                 *
                 *              > response.ErrorMessages.Add("Not a valid payment plan for public registration");
                 *
                 */

                #endregion


                #region Validate Password(s) Match
                if (model.Password != model.ConfirmPassword)
                {
                    response.isSuccess = false;

                    response.ErrorMessages.Add("Password and password confirmation do not match");
                }
                #endregion

                #region Validate Account Name:

                ValidationResponseType accountNameValidationResponse = ValidationManager.IsValidAccountName(model.AccountName);
                if (!accountNameValidationResponse.isValid)
                {
                    response.isSuccess = false;

                    response.ErrorMessages.Add(accountNameValidationResponse.validationMessage);

                    //return response;
                }

                #endregion

                #region Validate User Name

                ValidationResponseType firstNameValidationResponse = ValidationManager.IsValidFirstName(model.FirstName);
                if (!firstNameValidationResponse.isValid)
                {
                    response.isSuccess = false;

                    response.ErrorMessages.Add(firstNameValidationResponse.validationMessage);

                    //return response;
                }

                ValidationResponseType lastNameValidationResponse = ValidationManager.IsValidLastName(model.LastName);
                if (!lastNameValidationResponse.isValid)
                {
                    response.isSuccess = false;

                    response.ErrorMessages.Add(lastNameValidationResponse.validationMessage);

                    //return response;
                }

                #endregion


                #region Validate Email Unique (Optional)

                /*
                 * var userValidation = AccountUserManager.GetUserIdentity(model.Email);
                 * if (userValidation != null)
                 * {
                 *  response.isSuccess = false;
                 *  response.ErrorMessages.Add("Another account is associated with that email address, please provide another");
                 * }
                 */

                #endregion


                //If validation(s) fails, return the response:
                if (response.isSuccess == false)
                {
                    //Log Platform Activity
                    string errors = string.Empty;

                    foreach (string error in response.ErrorMessages)
                    {
                        errors += error + "|";
                    }

                    PlatformLogManager.LogActivity(CategoryType.Registration,
                                                   ActivityType.Registration_Failed,
                                                   String.Format("Registration failed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin),
                                                   String.Format("Errors:{0}", errors
                                                                 ));

                    //Return the response
                    response.ErrorMessage = "Could not register this account";
                    return(response);
                }

                #endregion


                // Generate AccountID ====================================
                Guid accountId = Guid.NewGuid();

                #region Register Initial AccountUser (AKA: AccountOwner)


                #region Validate & Create Account Owner User

                // Further validations and account owner creation:

                var registerUserResponse = AccountUserManager.RegisterAccountOwner(
                    model.FirstName,
                    model.LastName,
                    accountId.ToString(),
                    model.AccountName,
                    model.Email,
                    model.Password
                    );

                #endregion

                if (!registerUserResponse.isSuccess)
                {
                    //Log Platform Activity
                    string errors = string.Empty;

                    foreach (string error in registerUserResponse.ErrorMessages)
                    {
                        errors += error + "|";
                    }

                    PlatformLogManager.LogActivity(CategoryType.Registration,
                                                   ActivityType.Registration_Failed,
                                                   String.Format("Registration failed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin),
                                                   String.Format("Errors:{0}", errors
                                                                 ));

                    //Return the response
                    response.isSuccess    = false;
                    response.ErrorMessage = registerUserResponse.ErrorMessage;

                    response.ErrorMessages = registerUserResponse.ErrorMessages;

                    return(response);
                }

                //Get user back from result
                var user = (AccountUserIdentity)registerUserResponse.ResponseObject;

                #endregion

                #region Create Account

                try
                {
                    // Create Accounts =============================================================

                    InsertStatements insertStatements = new InsertStatements();
                    var insertResult = insertStatements.InsertNewAccount(model, accountId);

                    if (insertResult.isSuccess)
                    {
                        // (Optional) for certain scenrios
                        //Add user to account, make them the owner, and assign them as SuperAdmin role:
                        //AccountManager.AddUserToAccount(user.Id, AccountID.ToString(), true); // <-- Only for certain scenarios

                        response.isSuccess      = true;
                        response.SuccessMessage = Sahara.Core.Settings.Copy.PlatformMessages.AccountRegistration.SuccessMessage;

                        var origin = "";
                        if (model.Origin != null)
                        {
                            origin = "<br/><br/><b>Origin:</b> " + model.Origin;
                        }

                        var name  = "<br/><br/><b>Name:</b> " + model.FirstName + " " + model.LastName;
                        var email = "<br/><br/><b>Email:</b> " + model.Email;

                        var phone = "";
                        if (model.PhoneNumber != null)
                        {
                            phone = "<br/><br/><b>Phone:</b> " + model.PhoneNumber;
                        }

                        try
                        {
                            //Send an alert to the platform admin(s):
                            EmailManager.Send(
                                Settings.Endpoints.Emails.PlatformEmailAddresses,
                                Settings.Endpoints.Emails.FromRegistration,
                                "Registration",
                                "New Registrant",
                                "A new account named <b>'" + model.AccountName + "'</b> has just been registered." + name + email + phone + origin,
                                true
                                );
                        }
                        catch
                        {
                        }

                        //Log The Activity ------------ :
                        //PlatformLogManager.LogActivity(CategoryType.Registration,
                        //ActivityType.Registration_Succeeded,
                        //String.Format("Registration completed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin),
                        //String.Format("Name:'{0}', Email:'{1}', Origin:{2}", model.AccountName, model.Email, model.Origin));

                        PlatformLogManager.LogActivity(CategoryType.Account,
                                                       ActivityType.Account_Registered,
                                                       String.Format("Registration completed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin),
                                                       String.Format("Name:'{0}', Email:'{1}', Origin:{2}", model.AccountName, model.Email, model.Origin),
                                                       accountId.ToString(),
                                                       model.AccountName,
                                                       null,
                                                       null,
                                                       null,
                                                       null,
                                                       model.Origin);


                        return(response);
                    }
                    else
                    {
                        #region Error Handling
                        string error = insertResult.ErrorMessage;

                        AccountUser outUser = null;

                        //rollback user creation:
                        AccountUserManager.DeleteUser(user.Id, false, out outUser);

                        //Log The Activity ------------ :
                        PlatformLogManager.LogActivity(CategoryType.Registration,
                                                       ActivityType.Registration_Failed,
                                                       String.Format("Registration failed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin),
                                                       String.Format("Error:{0}", error));

                        //PlatformLogManager.LogActivity(ErrorLogActivity.PlatformError,
                        //String.Format("Registration failed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin),
                        //String.Format("Error:{0}", error));


                        response.isSuccess    = false;
                        response.ErrorMessage = error;

                        response.ErrorMessages.Add(error);

                        return(response);

                        #endregion
                    }
                }
                catch (Exception e)
                {
                    #region Error Handling
                    string error = String.Empty;

                    AccountUser outUser = null;

                    //rollback user creation:
                    AccountUserManager.DeleteUser(user.Id, false, out outUser);

                    try
                    {
                        error = e.Message;
                    }
                    catch
                    {
                        error = "An error occured";
                    }

                    //rollback user:
                    //To Do: AccountUserManager.DeleteUser(model.Email);

                    string errorDetails = String.Format("Registration failed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin);

                    //Log The Error(s) ------------ :
                    PlatformLogManager.LogActivity(CategoryType.Registration,
                                                   ActivityType.Registration_Error,
                                                   errorDetails,
                                                   String.Format("Error:{0}", error));



                    PlatformExceptionsHelper.LogExceptionAndAlertAdmins(
                        e,
                        "registering a new account for " + model.AccountName + " / " + model.Email + " / " + model.FirstName + " " + model.LastName + " from: " + model.Origin,
                        System.Reflection.MethodBase.GetCurrentMethod());


                    response.isSuccess    = false;
                    response.ErrorMessage = error;

                    response.ErrorMessages.Add(error);

                    return(response);

                    #endregion
                }



                #endregion
            }
            catch (Exception e)
            {
                //Log The Error(s) ------------ :
                PlatformLogManager.LogActivity(CategoryType.Registration,
                                               ActivityType.Registration_Error,
                                               String.Format("Registration failed for: '{0}' by: {1} from: {2}", model.AccountName, model.Email, model.Origin),
                                               String.Format("Error:{0}", e.Message));



                PlatformExceptionsHelper.LogExceptionAndAlertAdmins(
                    e,
                    "registering a new account for " + model.AccountName + " / " + model.Email + " / " + model.FirstName + " " + model.LastName + " from: " + model.Origin,
                    System.Reflection.MethodBase.GetCurrentMethod());



                response.isSuccess    = false;
                response.ErrorMessage = "An error occured when creating the account";

                response.ErrorMessages.Add(e.Message);

                try
                {
                    response.ErrorMessages.Add(e.InnerException.InnerException.Message);
                }
                catch
                {
                }

                return(response);
            }
        }