Example #1
0
        public static bool ValidateApiKey(string accountNameKey, string apiKey)     //, string loggingLabel = null, string loggingDetails = null)
        {
            var result = false;

            List <string> apiKeyStrings = null;

            string localCacheKey = accountNameKey + ":apiKeys";

            #region (Plan A) Get list of api strings from local cache

            try
            {
                apiKeyStrings = (List <string>)HttpRuntime.Cache[localCacheKey];
            }
            catch (Exception e)
            {
            }

            #endregion

            if (apiKeyStrings == null)
            {
                #region (Plan B) Get List of API strings from API Cache

                IDatabase cache = CoreServices.RedisConnectionMultiplexers.RedisMultiplexer.GetDatabase();

                string hashApiKey   = accountNameKey + ":apicache";
                string hashApiField = "apikeys";

                try
                {
                    var redisApiValue = cache.HashGet(hashApiKey, hashApiField);

                    if (redisApiValue.HasValue)
                    {
                        apiKeyStrings = JsonConvert.DeserializeObject <List <string> >(redisApiValue);
                    }
                }
                catch
                {
                }

                #endregion

                if (apiKeyStrings == null)
                {
                    List <ApiKeyModel> apiKeys = null;

                    #region (Plan C) Get list of API keys from Redis Cache

                    try
                    {
                        string hashMainKey   = accountNameKey + ":apikeys";
                        string hashMainField = "list";

                        try
                        {
                            var redisValue = cache.HashGet(hashMainKey, hashMainField);

                            if (redisValue.HasValue)
                            {
                                apiKeys = JsonConvert.DeserializeObject <List <ApiKeyModel> >(redisValue);
                            }
                        }
                        catch
                        {
                        }
                    }
                    catch (Exception e)
                    {
                        var error = e.Message;
                        //TODO: Log: error message for Redis call
                    }


                    #endregion

                    if (apiKeys == null)
                    {
                        #region (Plan D) Get list of API keys from WCF

                        var applicationApiKeysServiceClient = new ApplicationApiKeysService.ApplicationApiKeysServiceClient();

                        try
                        {
                            applicationApiKeysServiceClient.Open();

                            apiKeys = applicationApiKeysServiceClient.GetApiKeys(accountNameKey, Common.SharedClientKey).ToList();

                            WCFManager.CloseConnection(applicationApiKeysServiceClient);
                        }
                        catch (Exception e)
                        {
                            #region Manage Exception

                            string exceptionMessage = e.Message.ToString();

                            var    currentMethod       = System.Reflection.MethodBase.GetCurrentMethod();
                            string currentMethodString = currentMethod.DeclaringType.FullName + "." + currentMethod.Name;

                            // Abort the connection & manage the exception
                            WCFManager.CloseConnection(applicationApiKeysServiceClient, exceptionMessage, currentMethodString);

                            #endregion
                        }

                        #endregion
                    }

                    //Convert to list of strings
                    apiKeyStrings = new List <string>();
                    foreach (var key in apiKeys)
                    {
                        apiKeyStrings.Add(key.ApiKey.ToString());
                    }

                    //Cache into API specific cache
                    try
                    {
                        cache.HashSet(hashApiKey, hashApiField, JsonConvert.SerializeObject(apiKeyStrings), When.Always, CommandFlags.FireAndForget);
                    }
                    catch
                    {
                    }
                }

                //Cache locally
                HttpRuntime.Cache.Insert(localCacheKey, apiKeyStrings, null, DateTime.Now.AddMinutes(Common.ApiKeysCacheTimeInMinutes), TimeSpan.Zero);
            }

            if (apiKeyStrings != null)
            {
                if (apiKeyStrings.Contains(apiKey.ToLower()))
                {
                    result = true;

                    #region LOG USE OF API KEY HERE

                    #endregion
                }

                return(result);
            }
            else
            {
                return(result);
            }
        }
Example #2
0
        private static int LocalAccountCacheTimeInHours = 48; //<-- We cache the account locally for 2 days to avoid a Redis or WCF call on a hot account

        public static AccountManagementService.Account GetAccountObject(string accountNameKey)
        {
            AccountManagementService.Account account = null;

            #region (Plan A) Get Account from Local Cache

            bool   localCacheEmpty = false;
            string localCacheKey   = accountNameKey + ":account";

            try
            {
                account = (AccountManagementService.Account)HttpRuntime.Cache[localCacheKey];
            }
            catch (Exception e)
            {
                var error = e.Message;
                //TODO: Log: error message for local cache call
            }

            #endregion

            if (account == null)
            {
                localCacheEmpty = true;

                #region (Plan B) Get Account from Redis Cache

                try
                {
                    //First we attempt to get the account from the Redis Cache

                    IDatabase cache = CoreServices.RedisConnectionMultiplexers.RedisMultiplexer.GetDatabase();

                    string hashKey   = "accountbyname:" + accountNameKey;
                    string hashField = "model";

                    try
                    {
                        var redisValue = cache.HashGet(hashKey, hashField);
                        if (redisValue.HasValue)
                        {
                            account = JsonConvert.DeserializeObject <AccountManagementService.Account>(redisValue);
                        }
                    }
                    catch
                    {
                    }
                }
                catch (Exception e)
                {
                    var error = e.Message;
                }

                #endregion
            }
            if (account == null)
            {
                #region (Plan C) Get Account from WCF

                //If a failure occurs, or the redis cache is empty we get the user from the WCF service
                var accountManagementServiceClient = new AccountManagementService.AccountManagementServiceClient();

                try
                {
                    accountManagementServiceClient.Open();
                    account = accountManagementServiceClient.GetAccount(accountNameKey, Common.SharedClientKey);

                    //Close the connection
                    WCFManager.CloseConnection(accountManagementServiceClient);
                }
                catch (Exception e)
                {
                    #region Manage Exception

                    string exceptionMessage = e.Message.ToString();

                    var    currentMethod       = System.Reflection.MethodBase.GetCurrentMethod();
                    string currentMethodString = currentMethod.DeclaringType.FullName + "." + currentMethod.Name;

                    // Abort the connection & manage the exception
                    WCFManager.CloseConnection(accountManagementServiceClient, exceptionMessage, currentMethodString);

                    #endregion
                }

                #endregion
            }

            if (localCacheEmpty)
            {
                #region store Account into local cache

                //store string in local cache for a few moments:
                HttpRuntime.Cache.Insert(localCacheKey, account, null, DateTime.Now.AddHours(Common.LocalAccountCacheTimeInHours), TimeSpan.Zero);

                #endregion
            }

            return(account);
        }
Example #3
0
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            //GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);

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


            //Initialize Local Environment
            EnvironmentSettings.CurrentEnvironment.Site = WebConfigurationManager.AppSettings["Environment"];

            //Require HTTPS if on stage or production:
            if (EnvironmentSettings.CurrentEnvironment.Site.ToLower() == "stage" || EnvironmentSettings.CurrentEnvironment.Site.ToLower() == "production" || EnvironmentSettings.CurrentEnvironment.Site.ToLower() == "release" || EnvironmentSettings.CurrentEnvironment.Site.ToLower() == "staging")
            {
                GlobalFilters.Filters.Add(new RequireHttpsAttribute());
            }

            //Initialize Shared Client Key for WCF Calls
            Common.SharedClientKey = ConfigurationManager.AppSettings["SharedClientKey"];

            #region Communicate with CoreServices and get static settings for this client to work with

            //Each client can get necessary settings and endpoint information from CoreServices for each enviornment.
            //This happens when the appliation is first initialized, and is stored in a static class for performance
            //If CoreServices are updated, a restart of each client may be necessary to get updated settings

            var platformSettingsServiceClient = new PlatformSettingsService.PlatformSettingsServiceClient(); // <-- We only use PlatformSettingsServiceClient in EnviornmentSettings because it is ONLY used at application startup:

            //Get & Initialize Settings from CoreServices:

            try
            {
                // PLATFORM SETTINGS SERVICE --------------------------------------

                platformSettingsServiceClient.Open();
                var platformSettingsResult = platformSettingsServiceClient.GetCorePlatformSettings(Common.SharedClientKey);



                CoreServices.PlatformSettings = platformSettingsResult;
                EnvironmentSettings.CurrentEnvironment.CoreServices = platformSettingsResult.Environment.Current;

                // CONFIGURE REDIS CONNECTIONS --------------
                // Because the  ConnectionMultiplexer  does a lot, it is designed to be shared and reused between callers.
                // You should not create a  ConnectionMultiplexer  per operation. It is fully thread-safe and ready for this usage.
                // In all the subsequent examples it will be assumed that you have a  ConnectionMultiplexer  instance stored away for re-use.
                CoreServices.RedisConnectionMultiplexers.RedisMultiplexer = ConnectionMultiplexer.Connect(platformSettingsResult.Redis.Unsecure);
                //CoreServices.RedisConnectionMultiplexers.PlatformManager_Multiplexer = ConnectionMultiplexer.Connect(platformSettingsResult.Redis.PlatformManager_Unsecure);
                //CoreServices.RedisConnectionMultiplexers.AccountManager_Multiplexer = ConnectionMultiplexer.Connect(platformSettingsResult.Redis.AccountManager_Unsecure);


                // CONFIGURE SEARCH CONNECTIONS ---------- (Moved to search partitions)

                /*
                 * CoreServices.SearchServiceQueryClient = new Microsoft.Azure.Search.SearchServiceClient(
                 *  platformSettingsResult.Search.SearchServiceName,
                 *  new Microsoft.Azure.Search.SearchCredentials(
                 *      platformSettingsResult.Search.ClientQueryKey
                 *      )
                 * );*/


                // CONFIGURE DOCUMENT DATABSE CONNECTIONS using READ ONLY keys -------------

                /* NOT USED BY API ANY LONGER - SEARCH ONLY
                 * ConnectionPolicy _connectionPolicy = new ConnectionPolicy
                 * {
                 *  //Since we are running within Azure we use Direct/TCP connections for performance.
                 *  //Web clients can alo use this.
                 *  //External clients like mobile phones that have ReadOnly Keys should use Gateway/Https
                 *  ConnectionMode = ConnectionMode.Direct,
                 *  ConnectionProtocol = Protocol.Tcp
                 * };
                 *
                 * CoreServices.DocumentDatabases.Accounts_DocumentClient = new Microsoft.Azure.Documents.Client.DocumentClient(
                 *  new Uri(platformSettingsResult.DocumentDB.AccountPartitionsReadOnlyAccountName),
                 *  platformSettingsResult.DocumentDB.AccountPartitionsReadOnlyAccountKey,
                 *  _connectionPolicy
                 *  );
                 * CoreServices.DocumentDatabases.Accounts_DocumentClient.OpenAsync();
                 */

                //Close the connections
                WCFManager.CloseConnection(platformSettingsServiceClient); //<--Opens on init only
            }
            catch (Exception e)
            {
                #region Manage Exception

                string exceptionMessage = e.Message.ToString();

                var    currentMethod       = System.Reflection.MethodBase.GetCurrentMethod();
                string currentMethodString = currentMethod.DeclaringType.FullName + "." + currentMethod.Name;

                // Abort the connections & manage the exceptions
                WCFManager.CloseConnection(platformSettingsServiceClient, exceptionMessage, currentMethodString);

                #endregion

                platformSettingsServiceClient.Close();
                EnvironmentSettings.CurrentEnvironment.CoreServices = "error: " + exceptionMessage;
            }

            #endregion


            //Force ALL results as JSON
            GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

            //Register bundles last so options can be set by environment settings:
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }