private bool IsCacheRetrievalEnabled(IResourceDataRequest request)
        {
            bool isRead                  = request.Action == ResourceAction.Read;
            bool isLoginAttempt          = request.Type == typeof(ILoginAttempt);
            bool isProviderAccountAccess = request.Type == typeof(IProviderAccountAccess);
            bool isCollectionResource    = this.typeLookup.IsCollectionResponse(request.Type);
            bool isExpandedRequest       = request.Uri.ToString().Contains("expand=");

            return

                // Only consider cache retrieval for GETs
                (isRead &&

                 // Login attempts are always sent to the server
                 !isLoginAttempt &&

                 // Provider account access looks like an IAccount response, but it should not be cached
                 !isProviderAccountAccess &&

                 // Not currently caching collections
                 !isCollectionResource &&

                 // Always send expanded requests to the server
                 !isExpandedRequest);
        }
Esempio n. 2
0
 IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger)
 {
     if (request.Action == ResourceAction.Delete)
     {
         return(new DefaultResourceDataResult(ResourceAction.Delete, null, null, 204, null));
     }
     else
     {
         return(chain.Filter(request, logger));
     }
 }
 IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger)
 {
     if (request.Action == ResourceAction.Delete)
     {
         return new DefaultResourceDataResult(ResourceAction.Delete, null, null, 204, null);
     }
     else
     {
         return chain.Filter(request, logger);
     }
 }
Esempio n. 4
0
 Task <IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken)
 {
     if (request.Action == ResourceAction.Delete)
     {
         return(Task.FromResult <IResourceDataResult>(
                    new DefaultResourceDataResult(ResourceAction.Delete, null, null, 204, null)));
     }
     else
     {
         return(chain.FilterAsync(request, logger, cancellationToken));
     }
 }
        private void CacheNestedCustomDataUpdates(IResourceDataRequest request, IResourceDataResult result, ILogger logger)
        {
            object customDataObj = null;
            Map    customData    = null;

            if (!request.Properties.TryGetValue(AbstractExtendableInstanceResource.CustomDataPropertyName, out customDataObj))
            {
                return;
            }

            customData = customDataObj as Map;
            if (customData.IsNullOrEmpty())
            {
                return;
            }

            bool creating = request.Action == ResourceAction.Create;

            var parentHref = request.Uri.ResourcePath.ToString();

            if (creating && !result.Body.TryGetValueAsString(AbstractResource.HrefPropertyName, out parentHref))
            {
                return;
            }

            var customDataHref = parentHref + "/customData";

            var dataToCache = this.GetCachedValue(typeof(ICustomData), customDataHref);

            if (!creating && dataToCache == null)
            {
                logger.Trace($"Request {request.Uri} has nested custom data updates, but no authoritative cached custom data exists; aborting", "WriteCacheFilter.CacheNestedCustomDataUpdates");
                return;
            }

            logger.Trace($"Request {request.Uri} has nested custom data updates, updating cached custom data", "WriteCacheFilter.CacheNestedCustomDataUpdates");

            if (dataToCache.IsNullOrEmpty())
            {
                dataToCache = new Dictionary <string, object>();
            }

            foreach (var updatedItem in customData)
            {
                dataToCache[updatedItem.Key] = updatedItem.Value;
            }

            // Ensure the href property exists
            dataToCache[AbstractResource.HrefPropertyName] = customDataHref;

            this.Cache(typeof(ICustomData), dataToCache, logger);
        }
        public override IResourceDataResult Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger)
        {
            bool cacheEnabled = this.cacheResolver.IsSynchronousSupported;

            if (!cacheEnabled)
            {
                return(chain.Filter(request, logger));
            }

            bool isDelete = request.Action == ResourceAction.Delete;
            bool isCustomDataPropertyRequest = request.Uri.ResourcePath.ToString().Contains("/customData/");

            if (isCustomDataPropertyRequest && isDelete)
            {
                logger.Trace($"Request {request.Action} {request.Uri} is a custom data property delete, deleting cached property name if exists", "WriteCacheFilter.FilterAsync");
                this.UncacheCustomDataProperty(request.Uri.ResourcePath, logger);
            }
            else if (isDelete)
            {
                logger.Trace($"Request {request.Action} {request.Uri} is a resource deletion, purging from cache if exists", "WriteCacheFilter.Filter");
                var cacheKey = this.GetCacheKey(request);
                this.Uncache(request.Type, cacheKey);
            }

            var result = chain.Filter(request, logger);

            bool isEmailVerificationResponse = result.Type == typeof(IEmailVerificationToken);

            if (isEmailVerificationResponse)
            {
                logger.Trace($"Request {request.Action} {request.Uri} is an email verification request, purging account from cache if exists", "WriteCacheFilter.Filter");
                this.UncacheAccountOnEmailVerification(result);
            }

            bool possibleCustomDataUpdate = (request.Action == ResourceAction.Create || request.Action == ResourceAction.Update) &&
                                            AbstractExtendableInstanceResource.IsExtendable(request.Type);

            if (possibleCustomDataUpdate)
            {
                this.CacheNestedCustomDataUpdates(request, result, logger);
            }

            if (IsCacheable(request, result))
            {
                logger.Trace($"Caching request {request.Action} {request.Uri}", "WriteCacheFilter.Filter");
                this.Cache(result.Type, result.Body, logger);
            }

            return(result);
        }
 IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger)
 {
     if (request.Action == ResourceAction.Create)
     {
         return new DefaultResourceDataResult(
             ResourceAction.Create,
             typeof(IDictionary<string, object>),
             request.Uri,
             httpStatus: 200,
             body: new Dictionary<string, object>() { { "Foo", "bar" } });
     }
     else
     {
         return chain.Filter(request, logger);
     }
 }
        public override IResourceDataResult Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger)
        {
            bool cacheEnabled = this.cacheResolver.IsSynchronousSupported;
            if (!cacheEnabled)
            {
                return chain.Filter(request, logger);
            }

            bool isDelete = request.Action == ResourceAction.Delete;
            bool isCustomDataPropertyRequest = request.Uri.ResourcePath.ToString().Contains("/customData/");

            if (isCustomDataPropertyRequest && isDelete)
            {
                logger.Trace($"Request {request.Action} {request.Uri} is a custom data property delete, deleting cached property name if exists", "WriteCacheFilter.FilterAsync");
                this.UncacheCustomDataProperty(request.Uri.ResourcePath, logger);
            }
            else if (isDelete)
            {
                logger.Trace($"Request {request.Action} {request.Uri} is a resource deletion, purging from cache if exists", "WriteCacheFilter.Filter");
                var cacheKey = this.GetCacheKey(request);
                this.Uncache(request.Type, cacheKey);
            }

            var result = chain.Filter(request, logger);

            bool isEmailVerificationResponse = result.Type == typeof(IEmailVerificationToken);
            if (isEmailVerificationResponse)
            {
                logger.Trace($"Request {request.Action} {request.Uri} is an email verification request, purging account from cache if exists", "WriteCacheFilter.Filter");
                this.UncacheAccountOnEmailVerification(result);
            }

            bool possibleCustomDataUpdate = (request.Action == ResourceAction.Create || request.Action == ResourceAction.Update) &&
                AbstractExtendableInstanceResource.IsExtendable(request.Type);
            if (possibleCustomDataUpdate)
            {
                this.CacheNestedCustomDataUpdates(request, result, logger);
            }

            if (IsCacheable(request, result))
            {
                logger.Trace($"Caching request {request.Action} {request.Uri}", "WriteCacheFilter.Filter");
                this.Cache(result.Type, result.Body, logger);
            }

            return result;
        }
        IResourceDataResult ISynchronousFilterChain.Filter(IResourceDataRequest request, ILogger logger)
        {
            bool hasFilters = !this.filters.IsNullOrEmpty();
            if (!hasFilters)
            {
                throw new ApplicationException("Empty filter chain");
            }

            if (this.filters.Count == 1)
            {
                return this.filters.Single().Filter(
                    request,
                    chain: null,
                    logger: logger);
            }

            var remainingChain = new DefaultSynchronousFilterChain(this.dataStore, this.filters.Skip(1));
            return this.filters.First().Filter(request, remainingChain, logger);
        }
Esempio n. 10
0
 IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger)
 {
     if (request.Action == ResourceAction.Create)
     {
         return(new DefaultResourceDataResult(
                    ResourceAction.Create,
                    typeof(IDictionary <string, object>),
                    request.Uri,
                    httpStatus: 200,
                    body: new Dictionary <string, object>()
         {
             { "Foo", "bar" }
         }));
     }
     else
     {
         return(chain.Filter(request, logger));
     }
 }
Esempio n. 11
0
 Task <IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken)
 {
     if (request.Action == ResourceAction.Create)
     {
         return(Task.FromResult <IResourceDataResult>(new DefaultResourceDataResult(
                                                          ResourceAction.Create,
                                                          typeof(IDictionary <string, object>),
                                                          request.Uri,
                                                          httpStatus: 200,
                                                          body: new Dictionary <string, object>()
         {
             { "Foo", "bar" }
         })));
     }
     else
     {
         return(chain.FilterAsync(request, logger, cancellationToken));
     }
 }
        async Task <IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken)
        {
            var result = await chain.FilterAsync(request, logger, cancellationToken).ConfigureAwait(false);

            if (!IsCreateOrUpdate(request))
            {
                return(result); // short-circuit
            }

            if (!IsAccountStoreMapping(result))
            {
                return(result); // short-circuit
            }

            var applicationHref = GetContainerHref("application", result);

            if (!string.IsNullOrEmpty(applicationHref))
            {
                var application = await chain.DataStore.GetResourceSkipCacheAsync <IApplication>(applicationHref, cancellationToken).ConfigureAwait(false);

                var allMappings = await application.GetAccountStoreMappings().ToListAsync(cancellationToken).ConfigureAwait(false);

                logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Application '{applicationHref}'", "AccountStoreMappingCacheInvalidationFilter.FilterAsync");

                return(result); // done
            }

            var organizationHref = GetContainerHref("organization", result);

            if (!string.IsNullOrEmpty(organizationHref))
            {
                var organization = await chain.DataStore.GetResourceSkipCacheAsync <IOrganization>(organizationHref, cancellationToken).ConfigureAwait(false);

                var allMappings = await organization.GetAccountStoreMappings().ToListAsync(cancellationToken).ConfigureAwait(false);

                logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Organization '{organizationHref}'", "AccountStoreMappingCacheInvalidationFilter.FilterAsync");

                return(result); // done
            }

            throw new NotSupportedException($"Unsupported AccountStore container type: {request.Type.Name}");
        }
        private IResourceDataResult GetCachedResourceData(IResourceDataRequest request, ILogger logger)
        {
            // TODO isApiKeyCollectionQuery
            var cacheKey = this.GetCacheKey(request);

            if (string.IsNullOrEmpty(cacheKey))
            {
                logger.Warn($"Could not construct cacheKey for request {request.Uri}; aborting", "ReadCacheFilter.GetCachedResourceData");
                return(null);
            }

            var data = this.GetCachedValue(request.Type, cacheKey);

            if (data == null)
            {
                return(null);
            }

            return(new DefaultResourceDataResult(request.Action, request.Type, request.Uri, 200, data));
        }
        private static bool IsCacheable(IResourceDataRequest request, IResourceDataResult result)
        {
            bool hasData = !result.Body.IsNullOrEmpty();

            return

                // Must be a resource
                (IsResource(result?.Body) &&

                 // Don't cache password reset or email verification requests
                 result.Type != typeof(IPasswordResetToken) &&
                 result.Type != typeof(IEmailVerificationToken) &&
                 result.Type != typeof(IEmailVerificationRequest) &&

                 // Don't cache login attempts
                 result.Type != typeof(IAuthenticationResult) &&

                 // ProviderAccountResults look like IAccounts but should not be cached either
                 result.Type != typeof(IProviderAccountResult));
        }
        private async Task <IResourceDataResult> GetCachedResourceDataAsync(IResourceDataRequest request, ILogger logger, CancellationToken cancellationToken)
        {
            // TODO isApiKeyCollectionQuery
            var cacheKey = this.GetCacheKey(request);

            if (string.IsNullOrEmpty(cacheKey))
            {
                logger.Warn($"Could not construct cacheKey for request {request.Uri}; aborting", "ReadCacheFilter.GetCachedResourceDataAsync");
                return(null);
            }

            var data = await this.GetCachedValueAsync(request.Type, cacheKey, cancellationToken).ConfigureAwait(false);

            if (data == null)
            {
                return(null);
            }

            return(new DefaultResourceDataResult(request.Action, request.Type, request.Uri, 200, data));
        }
Esempio n. 16
0
        IResourceDataResult ISynchronousFilterChain.Filter(IResourceDataRequest request, ILogger logger)
        {
            bool hasFilters = !this.filters.IsNullOrEmpty();

            if (!hasFilters)
            {
                throw new ApplicationException("Empty filter chain");
            }

            if (this.filters.Count == 1)
            {
                return(this.filters.Single().Filter(
                           request,
                           chain: null,
                           logger: logger));
            }

            var remainingChain = new DefaultSynchronousFilterChain(this.dataStore, this.filters.Skip(1));

            return(this.filters.First().Filter(request, remainingChain, logger));
        }
        IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger)
        {
            var result = chain.Filter(request, logger);

            if (!IsCreateOrUpdate(request))
            {
                return(result); // short-circuit
            }

            if (!IsAccountStoreMapping(result))
            {
                return(result); // short-circuit
            }

            var applicationHref = GetContainerHref("application", result);

            if (!string.IsNullOrEmpty(applicationHref))
            {
                var application = chain.DataStore.GetResourceSkipCache <IApplication>(applicationHref);
                var allMappings = application.GetAccountStoreMappings().Synchronously().ToList();

                logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Application '{applicationHref}'", "AccountStoreMappingCacheInvalidationFilter.Filter");

                return(result); // done
            }

            var organizationHref = GetContainerHref("organization", result);

            if (!string.IsNullOrEmpty(organizationHref))
            {
                var organization = chain.DataStore.GetResourceSkipCache <IOrganization>(organizationHref);
                var allMappings  = organization.GetAccountStoreMappings().Synchronously().ToList();

                logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Organization '{organizationHref}'", "AccountStoreMappingCacheInvalidationFilter.Filter");

                return(result); // done
            }

            throw new NotSupportedException($"Unsupported AccountStore container type: {request.Type.Name}");
        }
        public override IResourceDataResult Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger)
        {
            bool cacheEnabled =
                this.cacheResolver.IsAsynchronousSupported
                && this.IsCacheRetrievalEnabled(request)
                && !request.SkipCache;
            if (cacheEnabled)
            {
                logger.Trace($"Checking cache for resource {request.Uri}", "ReadCacheFilter.Filter");
                var result = this.GetCachedResourceData(request, logger);

                if (result != null)
                {
                    logger.Trace($"Cache hit for {request.Uri}; returning cached data", "ReadCacheFilter.Filter");
                    return result; // short-circuit the remainder of the filter chain
                }

                logger.Trace($"Cache miss for {request.Uri}", "ReadCacheFilter.Filter");
            }

            return chain.Filter(request, logger);
        }
        public override async Task<IResourceDataResult> FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken)
        {
            bool cacheEnabled =
                this.cacheResolver.IsAsynchronousSupported
                && this.IsCacheRetrievalEnabled(request)
                && !request.SkipCache;
            if (cacheEnabled)
            {
                logger.Trace($"Checking cache for resource {request.Uri}", "ReadCacheFilter.FilterAsync");
                var result = await this.GetCachedResourceDataAsync(request, logger, cancellationToken).ConfigureAwait(false);

                if (result != null)
                {
                    logger.Trace($"Cache hit for {request.Uri}; returning cached data", "ReadCacheFilter.FilterAsync");
                    return result; // short-circuit the remainder of the filter chain
                }

                logger.Trace($"Cache miss for {request.Uri}", "ReadCacheFilter.FilterAsync");
            }

            return await chain.FilterAsync(request, logger, cancellationToken).ConfigureAwait(false);
        }
        IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger)
        {
            var result = chain.Filter(request, logger);

            if (!IsCreateOrUpdate(request))
            {
                return result; // short-circuit
            }

            if (!IsAccountStoreMapping(result))
            {
                return result; // short-circuit
            }

            var applicationHref = GetContainerHref("application", result);
            if (!string.IsNullOrEmpty(applicationHref))
            {
                var application = chain.DataStore.GetResourceSkipCache<IApplication>(applicationHref);
                var allMappings = application.GetAccountStoreMappings().Synchronously().ToList();

                logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Application '{applicationHref}'", "AccountStoreMappingCacheInvalidationFilter.Filter");

                return result; // done
            }

            var organizationHref = GetContainerHref("organization", result);
            if (!string.IsNullOrEmpty(organizationHref))
            {
                var organization = chain.DataStore.GetResourceSkipCache<IOrganization>(organizationHref);
                var allMappings = organization.GetAccountStoreMappings().Synchronously().ToList();

                logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Organization '{organizationHref}'", "AccountStoreMappingCacheInvalidationFilter.Filter");

                return result; // done
            }

            throw new NotSupportedException($"Unsupported AccountStore container type: {request.Type.Name}");
        }
        async Task<IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken)
        {
            var result = await chain.FilterAsync(request, logger, cancellationToken).ConfigureAwait(false);

            if (!IsCreateOrUpdate(request))
            {
                return result; // short-circuit
            }

            if (!IsAccountStoreMapping(result))
            {
                return result; // short-circuit
            }

            var applicationHref = GetContainerHref("application", result);
            if (!string.IsNullOrEmpty(applicationHref))
            {
                var application = await chain.DataStore.GetResourceSkipCacheAsync<IApplication>(applicationHref, cancellationToken).ConfigureAwait(false);
                var allMappings = await application.GetAccountStoreMappings().ToListAsync(cancellationToken).ConfigureAwait(false);

                logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Application '{applicationHref}'", "AccountStoreMappingCacheInvalidationFilter.FilterAsync");

                return result; // done
            }

            var organizationHref = GetContainerHref("organization", result);
            if (!string.IsNullOrEmpty(organizationHref))
            {
                var organization = await chain.DataStore.GetResourceSkipCacheAsync<IOrganization>(organizationHref, cancellationToken).ConfigureAwait(false);
                var allMappings = await organization.GetAccountStoreMappings().ToListAsync(cancellationToken).ConfigureAwait(false);

                logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Organization '{organizationHref}'", "AccountStoreMappingCacheInvalidationFilter.FilterAsync");

                return result; // done
            }

            throw new NotSupportedException($"Unsupported AccountStore container type: {request.Type.Name}");
        }
        public override async Task <IResourceDataResult> FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken)
        {
            bool cacheEnabled =
                this.cacheResolver.IsAsynchronousSupported &&
                this.IsCacheRetrievalEnabled(request) &&
                !request.SkipCache;

            if (cacheEnabled)
            {
                logger.Trace($"Checking cache for resource {request.Uri}", "ReadCacheFilter.FilterAsync");
                var result = await this.GetCachedResourceDataAsync(request, logger, cancellationToken).ConfigureAwait(false);

                if (result != null)
                {
                    logger.Trace($"Cache hit for {request.Uri}; returning cached data", "ReadCacheFilter.FilterAsync");
                    return(result); // short-circuit the remainder of the filter chain
                }

                logger.Trace($"Cache miss for {request.Uri}", "ReadCacheFilter.FilterAsync");
            }

            return(await chain.FilterAsync(request, logger, cancellationToken).ConfigureAwait(false));
        }
        public override IResourceDataResult Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger)
        {
            bool cacheEnabled =
                this.cacheResolver.IsAsynchronousSupported &&
                this.IsCacheRetrievalEnabled(request) &&
                !request.SkipCache;

            if (cacheEnabled)
            {
                logger.Trace($"Checking cache for resource {request.Uri}", "ReadCacheFilter.Filter");
                var result = this.GetCachedResourceData(request, logger);

                if (result != null)
                {
                    logger.Trace($"Cache hit for {request.Uri}; returning cached data", "ReadCacheFilter.Filter");
                    return(result); // short-circuit the remainder of the filter chain
                }

                logger.Trace($"Cache miss for {request.Uri}", "ReadCacheFilter.Filter");
            }

            return(chain.Filter(request, logger));
        }
 private static bool IsCreateOrUpdate(IResourceDataRequest request)
     => request.Action == ResourceAction.Create
     || request.Action == ResourceAction.Update;
 Task<IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken)
 {
     return this.filterFunc(request, chain, logger, cancellationToken);
 }
 IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger)
 {
     return this.filterFunc(request, chain, logger);
 }
        private async Task<IResourceDataResult> GetCachedResourceDataAsync(IResourceDataRequest request, ILogger logger, CancellationToken cancellationToken)
        {
            // TODO isApiKeyCollectionQuery
            var cacheKey = this.GetCacheKey(request);
            if (string.IsNullOrEmpty(cacheKey))
            {
                logger.Warn($"Could not construct cacheKey for request {request.Uri}; aborting", "ReadCacheFilter.GetCachedResourceDataAsync");
                return null;
            }

            var data = await this.GetCachedValueAsync(request.Type, cacheKey, cancellationToken).ConfigureAwait(false);

            if (data == null)
            {
                return null;
            }

            return new DefaultResourceDataResult(request.Action, request.Type, request.Uri, 200, data);
        }
        private static bool IsCacheable(IResourceDataRequest request, IResourceDataResult result)
        {
            bool hasData = !result.Body.IsNullOrEmpty();

            return

                // Must be a resource
                IsResource(result?.Body) &&

                // Don't cache password reset or email verification requests
                result.Type != typeof(IPasswordResetToken) &&
                result.Type != typeof(IEmailVerificationToken) &&
                result.Type != typeof(IEmailVerificationRequest) &&

                // Don't cache login attempts
                result.Type != typeof(IAuthenticationResult) &&

                // ProviderAccountResults look like IAccounts but should not be cached either
                result.Type != typeof(IProviderAccountResult);
        }
        private IResourceDataResult GetCachedResourceData(IResourceDataRequest request, ILogger logger)
        {
            // TODO isApiKeyCollectionQuery
            var cacheKey = this.GetCacheKey(request);
            if (string.IsNullOrEmpty(cacheKey))
            {
                logger.Warn($"Could not construct cacheKey for request {request.Uri}; aborting", "ReadCacheFilter.GetCachedResourceData");
                return null;
            }

            var data = this.GetCachedValue(request.Type, cacheKey);

            if (data == null)
            {
                return null;
            }

            return new DefaultResourceDataResult(request.Action, request.Type, request.Uri, 200, data);
        }
        IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger)
        {
            var result = chain.Filter(request, logger);

            return FilterCore(result);
        }
 public abstract Task<IResourceDataResult> FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken);
 protected string GetCacheKey(IResourceDataRequest request)
 {
     return this.GetCacheKey(request.Uri.ResourcePath.ToString());
 }
 public abstract IResourceDataResult Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger);
 Task<IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken)
 {
     if (request.Action == ResourceAction.Create)
     {
         return Task.FromResult<IResourceDataResult>(new DefaultResourceDataResult(
             ResourceAction.Create,
             typeof(IDictionary<string, object>),
             request.Uri,
             httpStatus: 200,
             body: new Dictionary<string, object>() { { "Foo", "bar" } }));
     }
     else
     {
         return chain.FilterAsync(request, logger, cancellationToken);
     }
 }
 Task<IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken)
 {
     if (request.Action == ResourceAction.Delete)
     {
         return Task.FromResult<IResourceDataResult>(
             new DefaultResourceDataResult(ResourceAction.Delete, null, null, 204, null));
     }
     else
     {
         return chain.FilterAsync(request, logger, cancellationToken);
     }
 }
 private static bool IsCreateOrUpdate(IResourceDataRequest request)
 => request.Action == ResourceAction.Create ||
 request.Action == ResourceAction.Update;
        private bool IsCacheRetrievalEnabled(IResourceDataRequest request)
        {
            bool isRead = request.Action == ResourceAction.Read;
            bool isLoginAttempt = request.Type == typeof(ILoginAttempt);
            bool isProviderAccountAccess = request.Type == typeof(IProviderAccountAccess);
            bool isCollectionResource = this.typeLookup.IsCollectionResponse(request.Type);
            bool isExpandedRequest = request.Uri.ToString().Contains("expand=");

            return

                // Only consider cache retrieval for GETs
                isRead &&

                // Login attempts are always sent to the server
                !isLoginAttempt &&

                // Provider account access looks like an IAccount response, but it should not be cached
                !isProviderAccountAccess &&

                // Not currently caching collections
                !isCollectionResource &&

                // Always send expanded requests to the server
                !isExpandedRequest;
        }
        async Task<IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken)
        {
            var result = await chain.FilterAsync(request, logger, cancellationToken).ConfigureAwait(false);

            return FilterCore(result);
        }
        async Task <IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken)
        {
            var result = await chain.FilterAsync(request, logger, cancellationToken).ConfigureAwait(false);

            return(FilterCore(result));
        }
 Task <IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken)
 {
     return(this.filterFunc(request, chain, logger, cancellationToken));
 }
        IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger)
        {
            var result = chain.Filter(request, logger);

            return(FilterCore(result));
        }
Esempio n. 42
0
 IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger)
 {
     return(this.filterFunc(request, chain, logger));
 }
Esempio n. 43
0
 public abstract Task <IResourceDataResult> FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken);
Esempio n. 44
0
 public abstract IResourceDataResult Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger);
        private void CacheNestedCustomDataUpdates(IResourceDataRequest request, IResourceDataResult result, ILogger logger)
        {
            object customDataObj = null;
            Map customData = null;

            if (!request.Properties.TryGetValue(AbstractExtendableInstanceResource.CustomDataPropertyName, out customDataObj))
            {
                return;
            }

            customData = customDataObj as Map;
            if (customData.IsNullOrEmpty())
            {
                return;
            }

            bool creating = request.Action == ResourceAction.Create;

            var parentHref = request.Uri.ResourcePath.ToString();
            if (creating && !result.Body.TryGetValueAsString(AbstractResource.HrefPropertyName, out parentHref))
            {
                return;
            }

            var customDataHref = parentHref + "/customData";

            var dataToCache = this.GetCachedValue(typeof(ICustomData), customDataHref);
            if (!creating && dataToCache == null)
            {
                logger.Trace($"Request {request.Uri} has nested custom data updates, but no authoritative cached custom data exists; aborting", "WriteCacheFilter.CacheNestedCustomDataUpdates");
                return;
            }

            logger.Trace($"Request {request.Uri} has nested custom data updates, updating cached custom data", "WriteCacheFilter.CacheNestedCustomDataUpdates");

            if (dataToCache.IsNullOrEmpty())
            {
                dataToCache = new Dictionary<string, object>();
            }

            foreach (var updatedItem in customData)
            {
                dataToCache[updatedItem.Key] = updatedItem.Value;
            }

            // Ensure the href property exists
            dataToCache[AbstractResource.HrefPropertyName] = customDataHref;

            this.Cache(typeof(ICustomData), dataToCache, logger);
        }
Esempio n. 46
0
 protected string GetCacheKey(IResourceDataRequest request)
 {
     return(this.GetCacheKey(request.Uri.ResourcePath.ToString()));
 }
Esempio n. 47
0
 private ResourceAction GetPostAction(IResourceDataRequest request, IHttpResponse httpResponse)
 => httpResponse.StatusCode == 201 ? ResourceAction.Create : request.Action;