mirror of
https://github.com/DuendeSoftware/products
synced 2026-05-24 01:18:22 +00:00
Add CT parameter to IResourceStore and IResourceStoreExtensions, flow through all implementations and tests
This commit is contained in:
parent
a533c397c0
commit
5df903ae44
17 changed files with 134 additions and 105 deletions
|
|
@ -43,7 +43,7 @@ public class Index : PageModel
|
|||
var client = await _clients.FindClientByIdAsync(grant.ClientId, HttpContext.RequestAborted);
|
||||
if (client != null)
|
||||
{
|
||||
var resources = await _resources.FindResourcesByScopeAsync(grant.Scopes);
|
||||
var resources = await _resources.FindResourcesByScopeAsync(grant.Scopes, HttpContext.RequestAborted);
|
||||
|
||||
var item = new GrantViewModel()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -52,8 +52,9 @@ public class ResourceStore : IResourceStore
|
|||
/// Finds the API resources by name.
|
||||
/// </summary>
|
||||
/// <param name="apiResourceNames">The names.</param>
|
||||
/// <param name="ct"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames)
|
||||
public virtual async Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames, CT ct)
|
||||
{
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("ResourceStore.FindApiResourcesByName");
|
||||
activity?.SetTag(Tracing.Properties.ApiResourceNames, apiResourceNames.ToSpaceSeparatedString());
|
||||
|
|
@ -72,7 +73,7 @@ public class ResourceStore : IResourceStore
|
|||
.Include(x => x.Properties)
|
||||
.AsNoTracking();
|
||||
|
||||
var result = (await apis.ToArrayAsync(CancellationTokenProvider.CancellationToken))
|
||||
var result = (await apis.ToArrayAsync(ct))
|
||||
.Where(x => apiResourceNames.Contains(x.Name))
|
||||
.Select(x => x.ToModel()).ToArray();
|
||||
|
||||
|
|
@ -92,8 +93,9 @@ public class ResourceStore : IResourceStore
|
|||
/// Gets API resources by scope name.
|
||||
/// </summary>
|
||||
/// <param name="scopeNames"></param>
|
||||
/// <param name="ct"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames)
|
||||
public virtual async Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames, CT ct)
|
||||
{
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("ResourceStore.FindApiResourcesByScopeName");
|
||||
activity?.SetTag(Tracing.Properties.ScopeNames, scopeNames.ToSpaceSeparatedString());
|
||||
|
|
@ -112,7 +114,7 @@ public class ResourceStore : IResourceStore
|
|||
.Include(x => x.Properties)
|
||||
.AsNoTracking();
|
||||
|
||||
var results = (await apis.ToArrayAsync(CancellationTokenProvider.CancellationToken))
|
||||
var results = (await apis.ToArrayAsync(ct))
|
||||
.Where(api => api.Scopes.Any(x => names.Contains(x.Scope)));
|
||||
var models = results.Select(x => x.ToModel()).ToArray();
|
||||
|
||||
|
|
@ -125,8 +127,9 @@ public class ResourceStore : IResourceStore
|
|||
/// Gets identity resources by scope name.
|
||||
/// </summary>
|
||||
/// <param name="scopeNames"></param>
|
||||
/// <param name="ct"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames)
|
||||
public virtual async Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames, CT ct)
|
||||
{
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("ResourceStore.FindIdentityResourcesByScopeName");
|
||||
activity?.SetTag(Tracing.Properties.ScopeNames, scopeNames.ToSpaceSeparatedString());
|
||||
|
|
@ -143,7 +146,7 @@ public class ResourceStore : IResourceStore
|
|||
.Include(x => x.Properties)
|
||||
.AsNoTracking();
|
||||
|
||||
var results = (await resources.ToArrayAsync(CancellationTokenProvider.CancellationToken))
|
||||
var results = (await resources.ToArrayAsync(ct))
|
||||
.Where(x => scopes.Contains(x.Name));
|
||||
|
||||
Logger.LogDebug("Found {scopes} identity scopes in database", results.Select(x => x.Name));
|
||||
|
|
@ -155,8 +158,9 @@ public class ResourceStore : IResourceStore
|
|||
/// Gets scopes by scope name.
|
||||
/// </summary>
|
||||
/// <param name="scopeNames"></param>
|
||||
/// <param name="ct"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames)
|
||||
public virtual async Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames, CT ct)
|
||||
{
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("ResourceStore.FindApiScopesByName");
|
||||
activity?.SetTag(Tracing.Properties.ScopeNames, scopeNames.ToSpaceSeparatedString());
|
||||
|
|
@ -173,7 +177,7 @@ public class ResourceStore : IResourceStore
|
|||
.Include(x => x.Properties)
|
||||
.AsNoTracking();
|
||||
|
||||
var results = (await resources.ToArrayAsync(CancellationTokenProvider.CancellationToken))
|
||||
var results = (await resources.ToArrayAsync(ct))
|
||||
.Where(x => scopes.Contains(x.Name));
|
||||
|
||||
Logger.LogDebug("Found {scopes} scopes in database", results.Select(x => x.Name));
|
||||
|
|
@ -185,7 +189,7 @@ public class ResourceStore : IResourceStore
|
|||
/// Gets all resources.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<Resources> GetAllResourcesAsync()
|
||||
public virtual async Task<Resources> GetAllResourcesAsync(CT ct)
|
||||
{
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("ResourceStore.GetAllResources");
|
||||
|
||||
|
|
@ -207,9 +211,9 @@ public class ResourceStore : IResourceStore
|
|||
.AsNoTracking();
|
||||
|
||||
var result = new Resources(
|
||||
(await identity.ToArrayAsync(CancellationTokenProvider.CancellationToken)).Select(x => x.ToModel()),
|
||||
(await apis.ToArrayAsync(CancellationTokenProvider.CancellationToken)).Select(x => x.ToModel()),
|
||||
(await scopes.ToArrayAsync(CancellationTokenProvider.CancellationToken)).Select(x => x.ToModel())
|
||||
(await identity.ToArrayAsync(ct)).Select(x => x.ToModel()),
|
||||
(await apis.ToArrayAsync(ct)).Select(x => x.ToModel()),
|
||||
(await scopes.ToArrayAsync(ct)).Select(x => x.ToModel())
|
||||
);
|
||||
|
||||
Logger.LogDebug("Found {scopes} as all scopes, and {apis} as API resources",
|
||||
|
|
|
|||
|
|
@ -16,12 +16,13 @@ public static class IResourceStoreExtensions
|
|||
/// </summary>
|
||||
/// <param name="store">The store.</param>
|
||||
/// <param name="scopeNames">The scope names.</param>
|
||||
/// <param name="ct">The <see cref="CT"/> used to propagate notifications that the operation should be cancelled.</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<Resources> FindResourcesByScopeAsync(this IResourceStore store, IEnumerable<string> scopeNames)
|
||||
public static async Task<Resources> FindResourcesByScopeAsync(this IResourceStore store, IEnumerable<string> scopeNames, CT ct)
|
||||
{
|
||||
var identity = await store.FindIdentityResourcesByScopeNameAsync(scopeNames);
|
||||
var apiResources = await store.FindApiResourcesByScopeNameAsync(scopeNames);
|
||||
var scopes = await store.FindApiScopesByNameAsync(scopeNames);
|
||||
var identity = await store.FindIdentityResourcesByScopeNameAsync(scopeNames, ct);
|
||||
var apiResources = await store.FindApiResourcesByScopeNameAsync(scopeNames, ct);
|
||||
var scopes = await store.FindApiScopesByNameAsync(scopeNames, ct);
|
||||
|
||||
ValidateNameUniqueness(identity, apiResources, scopes);
|
||||
|
||||
|
|
@ -88,17 +89,19 @@ public static class IResourceStoreExtensions
|
|||
/// </summary>
|
||||
/// <param name="store">The store.</param>
|
||||
/// <param name="scopeNames">The scope names.</param>
|
||||
/// <param name="ct">The <see cref="CT"/> used to propagate notifications that the operation should be cancelled.</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<Resources> FindEnabledResourcesByScopeAsync(this IResourceStore store, IEnumerable<string> scopeNames) => (await store.FindResourcesByScopeAsync(scopeNames)).FilterEnabled();
|
||||
public static async Task<Resources> FindEnabledResourcesByScopeAsync(this IResourceStore store, IEnumerable<string> scopeNames, CT ct) => (await store.FindResourcesByScopeAsync(scopeNames, ct)).FilterEnabled();
|
||||
|
||||
/// <summary>
|
||||
/// Gets all enabled resources.
|
||||
/// </summary>
|
||||
/// <param name="store">The store.</param>
|
||||
/// <param name="ct">The <see cref="CT"/> used to propagate notifications that the operation should be cancelled.</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<Resources> GetAllEnabledResourcesAsync(this IResourceStore store)
|
||||
public static async Task<Resources> GetAllEnabledResourcesAsync(this IResourceStore store, CT ct)
|
||||
{
|
||||
var resources = await store.GetAllResourcesAsync();
|
||||
var resources = await store.GetAllResourcesAsync(ct);
|
||||
ValidateNameUniqueness(resources.IdentityResources, resources.ApiResources, resources.ApiScopes);
|
||||
|
||||
return resources.FilterEnabled();
|
||||
|
|
@ -109,11 +112,15 @@ public static class IResourceStoreExtensions
|
|||
/// </summary>
|
||||
/// <param name="store">The store.</param>
|
||||
/// <param name="scopeNames">The scope names.</param>
|
||||
/// <param name="ct">The <see cref="CT"/> used to propagate notifications that the operation should be cancelled.</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<IEnumerable<IdentityResource>> FindEnabledIdentityResourcesByScopeAsync(this IResourceStore store, IEnumerable<string> scopeNames) => (await store.FindIdentityResourcesByScopeNameAsync(scopeNames)).Where(x => x.Enabled).ToArray();
|
||||
public static async Task<IEnumerable<IdentityResource>> FindEnabledIdentityResourcesByScopeAsync(this IResourceStore store, IEnumerable<string> scopeNames, CT ct) => (await store.FindIdentityResourcesByScopeNameAsync(scopeNames, ct)).Where(x => x.Enabled).ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Finds the enabled API resources by name.
|
||||
/// </summary>
|
||||
public static async Task<IEnumerable<ApiResource>> FindEnabledApiResourcesByNameAsync(this IResourceStore store, IEnumerable<string> resourceNames) => (await store.FindApiResourcesByNameAsync(resourceNames)).Where(x => x.Enabled).ToArray();
|
||||
/// <param name="store">The store.</param>
|
||||
/// <param name="resourceNames">The resource names.</param>
|
||||
/// <param name="ct">The <see cref="CT"/> used to propagate notifications that the operation should be cancelled.</param>
|
||||
public static async Task<IEnumerable<ApiResource>> FindEnabledApiResourcesByNameAsync(this IResourceStore store, IEnumerable<string> resourceNames, CT ct) => (await store.FindApiResourcesByNameAsync(resourceNames, ct)).Where(x => x.Enabled).ToArray();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ public class DiscoveryResponseGenerator : IDiscoveryResponseGenerator
|
|||
Options.Discovery.ShowApiScopes ||
|
||||
Options.Discovery.ShowClaims)
|
||||
{
|
||||
var resources = await ResourceStore.GetAllEnabledResourcesAsync();
|
||||
var resources = await ResourceStore.GetAllEnabledResourcesAsync(default);
|
||||
var scopes = new List<string>();
|
||||
|
||||
// scopes
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ public class UserInfoResponseGenerator : IUserInfoResponseGenerator
|
|||
Logger.LogDebug("Scopes in access token: {scopes}", scopeString);
|
||||
|
||||
// if we ever parameterized identity scopes, then we would need to invoke the resource validator's parse API here
|
||||
var identityResources = await Resources.FindEnabledIdentityResourcesByScopeAsync(scopes);
|
||||
var identityResources = await Resources.FindEnabledIdentityResourcesByScopeAsync(scopes, default);
|
||||
|
||||
var resources = new Resources(identityResources, Enumerable.Empty<ApiResource>(), Enumerable.Empty<ApiScope>());
|
||||
var result = new ResourceValidationResult(resources);
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ public class CachingResourceStore<T> : IResourceStore
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<Resources> GetAllResourcesAsync()
|
||||
public async Task<Resources> GetAllResourcesAsync(CT ct)
|
||||
{
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("CachingResourceStore.GetAllResources");
|
||||
|
||||
|
|
@ -88,13 +88,13 @@ public class CachingResourceStore<T> : IResourceStore
|
|||
|
||||
var all = await _allCache.GetOrAddAsync(key,
|
||||
_options.Caching.ResourceStoreExpiration,
|
||||
async () => await _inner.GetAllResourcesAsync());
|
||||
async () => await _inner.GetAllResourcesAsync(ct));
|
||||
|
||||
return all;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames)
|
||||
public async Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames, CT ct)
|
||||
{
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("CachingResourceStore.FindApiResourcesByScopeName");
|
||||
activity?.SetTag(Tracing.Properties.ScopeNames, scopeNames.ToSpaceSeparatedString());
|
||||
|
|
@ -133,7 +133,7 @@ public class CachingResourceStore<T> : IResourceStore
|
|||
// do the cache/DB lookup
|
||||
var resources = await _allCache.GetOrAddAsync(allCacheItemsKey, itemsDuration, async () =>
|
||||
{
|
||||
var results = await _inner.FindApiResourcesByScopeNameAsync(uncachedScopes);
|
||||
var results = await _inner.FindApiResourcesByScopeNameAsync(uncachedScopes, ct);
|
||||
return new Resources(null, results, null);
|
||||
});
|
||||
|
||||
|
|
@ -160,51 +160,52 @@ public class CachingResourceStore<T> : IResourceStore
|
|||
}
|
||||
|
||||
// now that we have all the ApiResource names, just use our other API (that should find the cacted items)
|
||||
return await FindApiResourcesByNameAsync(apiResourceNames);
|
||||
return await FindApiResourcesByNameAsync(apiResourceNames, ct);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames)
|
||||
public async Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames, CT ct)
|
||||
{
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("CachingResourceStore.FindApiResourcesByName");
|
||||
activity?.SetTag(Tracing.Properties.ApiResourceNames, apiResourceNames.ToSpaceSeparatedString());
|
||||
|
||||
return await FindItemsAsync(apiResourceNames, _apiResourceCache,
|
||||
async names => new Resources(null, await _inner.FindApiResourcesByNameAsync(names), null),
|
||||
x => x.ApiResources, x => x.Name, "ApiResources-");
|
||||
async (names, innerCt) => new Resources(null, await _inner.FindApiResourcesByNameAsync(names, innerCt), null),
|
||||
x => x.ApiResources, x => x.Name, "ApiResources-", ct);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames)
|
||||
public async Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames, CT ct)
|
||||
{
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("CachingResourceStore.FindIdentityResourcesByScopeName");
|
||||
activity?.SetTag(Tracing.Properties.ScopeNames, scopeNames.ToSpaceSeparatedString());
|
||||
|
||||
return await FindItemsAsync(scopeNames, _identityCache,
|
||||
async names => new Resources(await _inner.FindIdentityResourcesByScopeNameAsync(names), null, null),
|
||||
x => x.IdentityResources, x => x.Name, "IdentityResources-");
|
||||
async (names, innerCt) => new Resources(await _inner.FindIdentityResourcesByScopeNameAsync(names, innerCt), null, null),
|
||||
x => x.IdentityResources, x => x.Name, "IdentityResources-", ct);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames)
|
||||
public async Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames, CT ct)
|
||||
{
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("CachingResourceStore.FindApiScopesByName");
|
||||
activity?.SetTag(Tracing.Properties.ScopeNames, scopeNames.ToSpaceSeparatedString());
|
||||
|
||||
return await FindItemsAsync(scopeNames, _apiScopeCache,
|
||||
async names => new Resources(null, null, await _inner.FindApiScopesByNameAsync(names)),
|
||||
x => x.ApiScopes, x => x.Name, "ApiScopes-");
|
||||
async (names, innerCt) => new Resources(null, null, await _inner.FindApiScopesByNameAsync(names, innerCt)),
|
||||
x => x.ApiScopes, x => x.Name, "ApiScopes-", ct);
|
||||
}
|
||||
|
||||
|
||||
private async Task<IEnumerable<TItem>> FindItemsAsync<TItem>(
|
||||
IEnumerable<string> names,
|
||||
ICache<TItem> cache,
|
||||
Func<IEnumerable<string>, Task<Resources>> getResourcesFunc,
|
||||
Func<IEnumerable<string>, CT, Task<Resources>> getResourcesFunc,
|
||||
Func<Resources, IEnumerable<TItem>> getFromResourcesFunc,
|
||||
Func<TItem, string> getNameFunc,
|
||||
string allCachePrefix
|
||||
string allCachePrefix,
|
||||
CT ct
|
||||
)
|
||||
where TItem : class
|
||||
{
|
||||
|
|
@ -237,7 +238,7 @@ public class CachingResourceStore<T> : IResourceStore
|
|||
// expire this entry much faster than the normal items
|
||||
var itemsDuration = _options.Caching.ResourceStoreExpiration / 20;
|
||||
// do the cache/DB lookup
|
||||
var resources = await _allCache.GetOrAddAsync(allCacheItemsKey, itemsDuration, async () => await getResourcesFunc(uncachedNames));
|
||||
var resources = await _allCache.GetOrAddAsync(allCacheItemsKey, itemsDuration, async () => await getResourcesFunc(uncachedNames, ct));
|
||||
|
||||
// get the specific items from the Resources object
|
||||
var uncachedItems = getFromResourcesFunc(resources);
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ namespace Duende.IdentityServer.Stores.Empty;
|
|||
|
||||
internal class EmptyResourceStore : IResourceStore
|
||||
{
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames) => Task.FromResult(Enumerable.Empty<ApiResource>());
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames, CT ct) => Task.FromResult(Enumerable.Empty<ApiResource>());
|
||||
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames) => Task.FromResult(Enumerable.Empty<ApiResource>());
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames, CT ct) => Task.FromResult(Enumerable.Empty<ApiResource>());
|
||||
|
||||
public Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames) => Task.FromResult(Enumerable.Empty<ApiScope>());
|
||||
public Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames, CT ct) => Task.FromResult(Enumerable.Empty<ApiScope>());
|
||||
|
||||
public Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames) => Task.FromResult(Enumerable.Empty<IdentityResource>());
|
||||
public Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames, CT ct) => Task.FromResult(Enumerable.Empty<IdentityResource>());
|
||||
|
||||
public Task<Resources> GetAllResourcesAsync() => Task.FromResult(new Resources() { OfflineAccess = true });
|
||||
public Task<Resources> GetAllResourcesAsync(CT ct) => Task.FromResult(new Resources() { OfflineAccess = true });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public class InMemoryResourcesStore : IResourceStore
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task<Resources> GetAllResourcesAsync()
|
||||
public Task<Resources> GetAllResourcesAsync(CT ct)
|
||||
{
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("InMemoryResourceStore.GetAllResources");
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ public class InMemoryResourcesStore : IResourceStore
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames)
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames, CT ct)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(apiResourceNames);
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("InMemoryResourceStore.FindApiResourcesByName");
|
||||
|
|
@ -67,7 +67,7 @@ public class InMemoryResourcesStore : IResourceStore
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames)
|
||||
public Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames, CT ct)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(scopeNames);
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("InMemoryResourceStore.FindIdentityResourcesByScopeName");
|
||||
|
|
@ -81,7 +81,7 @@ public class InMemoryResourcesStore : IResourceStore
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames)
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames, CT ct)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(scopeNames);
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("InMemoryResourceStore.FindApiResourcesByScopeName");
|
||||
|
|
@ -95,7 +95,7 @@ public class InMemoryResourcesStore : IResourceStore
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames)
|
||||
public Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames, CT ct)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(scopeNames);
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("InMemoryResourceStore.FindApiScopesByName");
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ public class ApiSecretValidator : IApiSecretValidator
|
|||
}
|
||||
|
||||
// load API resource
|
||||
var apis = await _resources.FindApiResourcesByNameAsync(new[] { parsedSecret.Id });
|
||||
var apis = await _resources.FindApiResourcesByNameAsync(new[] { parsedSecret.Id }, context.RequestAborted);
|
||||
if (apis == null || !apis.Any())
|
||||
{
|
||||
await RaiseFailureEventAsync(parsedSecret.Id, "Unknown API resource");
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public class DefaultResourceValidator : IResourceValidator
|
|||
|
||||
var scopeNames = parsedScopesResult.ParsedScopes.Select(x => x.ParsedName).Distinct().ToArray();
|
||||
// todo: this API might want to pass resource indicators to better filter
|
||||
var scopeResourcesFromStore = await _store.FindEnabledResourcesByScopeAsync(scopeNames);
|
||||
var scopeResourcesFromStore = await _store.FindEnabledResourcesByScopeAsync(scopeNames, default);
|
||||
|
||||
if (request.ResourceIndicators?.Any() == true)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1106,12 +1106,12 @@ internal class TokenRequestValidator : ITokenRequestValidator
|
|||
var clientAllowedScopes = new List<string>();
|
||||
if (!ignoreImplicitIdentityScopes)
|
||||
{
|
||||
var resources = await _resourceStore.FindResourcesByScopeAsync(_validatedRequest.Client.AllowedScopes);
|
||||
var resources = await _resourceStore.FindResourcesByScopeAsync(_validatedRequest.Client.AllowedScopes, _ct);
|
||||
clientAllowedScopes.AddRange(resources.ToScopeNames().Where(x => _validatedRequest.Client.AllowedScopes.Contains(x)));
|
||||
}
|
||||
else
|
||||
{
|
||||
var apiScopes = await _resourceStore.FindApiScopesByNameAsync(_validatedRequest.Client.AllowedScopes);
|
||||
var apiScopes = await _resourceStore.FindApiScopesByNameAsync(_validatedRequest.Client.AllowedScopes, _ct);
|
||||
clientAllowedScopes.AddRange(apiScopes.Select(x => x.Name));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,25 +16,34 @@ public interface IResourceStore
|
|||
/// <summary>
|
||||
/// Gets identity resources by scope name.
|
||||
/// </summary>
|
||||
Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames);
|
||||
/// <param name="scopeNames">The scope names.</param>
|
||||
/// <param name="ct">The <see cref="CT"/> used to propagate notifications that the operation should be cancelled.</param>
|
||||
Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames, CT ct);
|
||||
|
||||
/// <summary>
|
||||
/// Gets API scopes by scope name.
|
||||
/// </summary>
|
||||
Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames);
|
||||
/// <param name="scopeNames">The scope names.</param>
|
||||
/// <param name="ct">The <see cref="CT"/> used to propagate notifications that the operation should be cancelled.</param>
|
||||
Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames, CT ct);
|
||||
|
||||
/// <summary>
|
||||
/// Gets API resources by scope name.
|
||||
/// </summary>
|
||||
Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames);
|
||||
/// <param name="scopeNames">The scope names.</param>
|
||||
/// <param name="ct">The <see cref="CT"/> used to propagate notifications that the operation should be cancelled.</param>
|
||||
Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames, CT ct);
|
||||
|
||||
/// <summary>
|
||||
/// Gets API resources by API resource name.
|
||||
/// </summary>
|
||||
Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames);
|
||||
/// <param name="apiResourceNames">The API resource names.</param>
|
||||
/// <param name="ct">The <see cref="CT"/> used to propagate notifications that the operation should be cancelled.</param>
|
||||
Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames, CT ct);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all resources.
|
||||
/// </summary>
|
||||
Task<Resources> GetAllResourcesAsync();
|
||||
/// <param name="ct">The <see cref="CT"/> used to propagate notifications that the operation should be cancelled.</param>
|
||||
Task<Resources> GetAllResourcesAsync(CT ct);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ namespace Duende.IdentityServer.IntegrationTests.EntityFramework.Storage.Stores;
|
|||
|
||||
public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbContext, ConfigurationStoreOptions>
|
||||
{
|
||||
private readonly CT _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
public ScopeStoreTests(DatabaseProviderFixture<ConfigurationDbContext> fixture) : base(fixture)
|
||||
{
|
||||
foreach (var options in TestDatabaseProviders)
|
||||
|
|
@ -76,7 +78,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
await using (var context = new ConfigurationDbContext(options))
|
||||
{
|
||||
var store = new ResourceStore(context, new NullLogger<ResourceStore>(), new NoneCancellationTokenProvider());
|
||||
foundResource = (await store.FindApiResourcesByNameAsync(new[] { resource.Name })).SingleOrDefault();
|
||||
foundResource = (await store.FindApiResourcesByNameAsync(new[] { resource.Name }, _ct)).SingleOrDefault();
|
||||
}
|
||||
|
||||
foundResource.ShouldNotBeNull();
|
||||
|
|
@ -105,7 +107,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
await using (var context = new ConfigurationDbContext(options))
|
||||
{
|
||||
var store = new ResourceStore(context, new NullLogger<ResourceStore>(), new NoneCancellationTokenProvider());
|
||||
foundResource = (await store.FindApiResourcesByNameAsync(new[] { resource.Name })).SingleOrDefault();
|
||||
foundResource = (await store.FindApiResourcesByNameAsync(new[] { resource.Name }, _ct)).SingleOrDefault();
|
||||
}
|
||||
|
||||
foundResource.ShouldNotBeNull();
|
||||
|
|
@ -140,7 +142,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
resources = await store.FindApiResourcesByScopeNameAsync(new List<string>
|
||||
{
|
||||
testApiScope.Name
|
||||
});
|
||||
}, _ct);
|
||||
}
|
||||
|
||||
resources.ShouldNotBeNull();
|
||||
|
|
@ -171,7 +173,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
await using (var context = new ConfigurationDbContext(options))
|
||||
{
|
||||
var store = new ResourceStore(context, new NullLogger<ResourceStore>(), new NoneCancellationTokenProvider());
|
||||
resources = await store.FindApiResourcesByScopeNameAsync(new[] { testApiScope.Name });
|
||||
resources = await store.FindApiResourcesByScopeNameAsync(new[] { testApiScope.Name }, _ct);
|
||||
}
|
||||
|
||||
resources.ShouldNotBeNull();
|
||||
|
|
@ -197,7 +199,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
resources = (await store.FindIdentityResourcesByScopeNameAsync(new List<string>
|
||||
{
|
||||
resource.Name
|
||||
})).ToList();
|
||||
}, _ct)).ToList();
|
||||
}
|
||||
|
||||
resources.ShouldNotBeNull();
|
||||
|
|
@ -228,7 +230,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
resources = (await store.FindIdentityResourcesByScopeNameAsync(new List<string>
|
||||
{
|
||||
resource.Name
|
||||
})).ToList();
|
||||
}, _ct)).ToList();
|
||||
}
|
||||
|
||||
resources.ShouldNotBeNull();
|
||||
|
|
@ -254,7 +256,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
resources = (await store.FindApiScopesByNameAsync(new List<string>
|
||||
{
|
||||
resource.Name
|
||||
})).ToList();
|
||||
}, _ct)).ToList();
|
||||
}
|
||||
|
||||
resources.ShouldNotBeNull();
|
||||
|
|
@ -285,7 +287,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
resources = (await store.FindApiScopesByNameAsync(new List<string>
|
||||
{
|
||||
resource.Name
|
||||
})).ToList();
|
||||
}, _ct)).ToList();
|
||||
}
|
||||
|
||||
resources.ShouldNotBeNull();
|
||||
|
|
@ -329,7 +331,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
await using (var context = new ConfigurationDbContext(options))
|
||||
{
|
||||
var store = new ResourceStore(context, new NullLogger<ResourceStore>(), new NoneCancellationTokenProvider());
|
||||
resources = await store.GetAllResourcesAsync();
|
||||
resources = await store.GetAllResourcesAsync(_ct);
|
||||
}
|
||||
|
||||
resources.ShouldNotBeNull();
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ namespace IdentityServer.UnitTests.Caches;
|
|||
|
||||
public class ResourceStoreCacheTests
|
||||
{
|
||||
private readonly CT _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
private List<Client> _clients { get; set; } = new List<Client>();
|
||||
private List<IdentityResource> _identityResources { get; set; } = new List<IdentityResource>();
|
||||
private List<ApiResource> _resources { get; set; } = new List<ApiResource>();
|
||||
|
|
@ -55,7 +57,7 @@ public class ResourceStoreCacheTests
|
|||
var store = _provider.GetRequiredService<IResourceStore>();
|
||||
cache.CacheItems.Count.ShouldBe(0);
|
||||
|
||||
var results = await store.FindIdentityResourcesByScopeNameAsync(new[] { "profile" });
|
||||
var results = await store.FindIdentityResourcesByScopeNameAsync(new[] { "profile" }, _ct);
|
||||
|
||||
cache.CacheItems.Count.ShouldBe(1);
|
||||
cache.CacheItems.First().Value.Value.Name.ShouldBe("profile");
|
||||
|
|
@ -69,7 +71,7 @@ public class ResourceStoreCacheTests
|
|||
var store = _provider.GetRequiredService<IResourceStore>();
|
||||
cache.CacheItems.Count.ShouldBe(0);
|
||||
|
||||
var results = await store.FindApiResourcesByScopeNameAsync(new[] { "scope1" });
|
||||
var results = await store.FindApiResourcesByScopeNameAsync(new[] { "scope1" }, _ct);
|
||||
|
||||
cache.CacheItems.Count.ShouldBe(1);
|
||||
cache.CacheItems.First().Value.Value.Names.Single().ShouldBe("urn:api1");
|
||||
|
|
@ -82,7 +84,7 @@ public class ResourceStoreCacheTests
|
|||
var store = _provider.GetRequiredService<IResourceStore>();
|
||||
cache.CacheItems.Count.ShouldBe(0);
|
||||
|
||||
var results = await store.FindApiScopesByNameAsync(new[] { "scope1" });
|
||||
var results = await store.FindApiScopesByNameAsync(new[] { "scope1" }, _ct);
|
||||
|
||||
cache.CacheItems.Count.ShouldBe(1);
|
||||
cache.CacheItems.First().Value.Value.Name.ShouldBe("scope1");
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ namespace UnitTests.Extensions;
|
|||
|
||||
public class IResourceStoreExtensionsTests
|
||||
{
|
||||
private readonly CT _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
[Fact]
|
||||
public async Task GetAllEnabledResourcesAsync_on_duplicate_identity_scopes_should_fail()
|
||||
{
|
||||
|
|
@ -19,7 +21,7 @@ public class IResourceStoreExtensionsTests
|
|||
new IdentityResource { Name = "A" } }
|
||||
};
|
||||
|
||||
Func<Task> a = () => store.GetAllEnabledResourcesAsync();
|
||||
Func<Task> a = () => store.GetAllEnabledResourcesAsync(_ct);
|
||||
var exception = await a.ShouldThrowAsync<Exception>();
|
||||
exception.Message.ShouldMatch("Duplicate identity scopes*");
|
||||
}
|
||||
|
|
@ -34,7 +36,7 @@ public class IResourceStoreExtensionsTests
|
|||
new IdentityResource { Name = "B" } }
|
||||
};
|
||||
|
||||
await store.GetAllEnabledResourcesAsync();
|
||||
await store.GetAllEnabledResourcesAsync(_ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -45,7 +47,7 @@ public class IResourceStoreExtensionsTests
|
|||
ApiResources = { new ApiResource { Name = "a" }, new ApiResource { Name = "a" } }
|
||||
};
|
||||
|
||||
Func<Task> a = () => store.GetAllEnabledResourcesAsync();
|
||||
Func<Task> a = () => store.GetAllEnabledResourcesAsync(_ct);
|
||||
var exception = await a.ShouldThrowAsync<Exception>();
|
||||
exception.Message.ShouldMatch("Duplicate api resources*");
|
||||
}
|
||||
|
|
@ -58,7 +60,7 @@ public class IResourceStoreExtensionsTests
|
|||
ApiResources = { new ApiResource("A"), new ApiResource("B") }
|
||||
};
|
||||
|
||||
await store.GetAllEnabledResourcesAsync();
|
||||
await store.GetAllEnabledResourcesAsync(_ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -71,7 +73,7 @@ public class IResourceStoreExtensionsTests
|
|||
new IdentityResource { Name = "A" } }
|
||||
};
|
||||
|
||||
Func<Task> a = () => store.FindResourcesByScopeAsync(new string[] { "A" });
|
||||
Func<Task> a = () => store.FindResourcesByScopeAsync(new string[] { "A" }, _ct);
|
||||
var exception = await a.ShouldThrowAsync<Exception>();
|
||||
exception.Message.ShouldMatch("Duplicate identity scopes*");
|
||||
}
|
||||
|
|
@ -86,7 +88,7 @@ public class IResourceStoreExtensionsTests
|
|||
new IdentityResource { Name = "B" } }
|
||||
};
|
||||
|
||||
await store.FindResourcesByScopeAsync(new string[] { "A" });
|
||||
await store.FindResourcesByScopeAsync(new string[] { "A" }, _ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -103,7 +105,7 @@ public class IResourceStoreExtensionsTests
|
|||
}
|
||||
};
|
||||
|
||||
var result = await store.FindResourcesByScopeAsync(new string[] { "a" });
|
||||
var result = await store.FindResourcesByScopeAsync(new string[] { "a" }, _ct);
|
||||
result.ApiResources.Count.ShouldBe(2);
|
||||
result.ApiScopes.Count.ShouldBe(1);
|
||||
result.ApiResources.Select(x => x.Name).ShouldBe(["api1", "api2"]);
|
||||
|
|
@ -118,7 +120,7 @@ public class IResourceStoreExtensionsTests
|
|||
ApiResources = { new ApiResource("A"), new ApiResource("B") }
|
||||
};
|
||||
|
||||
await store.FindResourcesByScopeAsync(new string[] { "A" });
|
||||
await store.FindResourcesByScopeAsync(new string[] { "A" }, _ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -136,7 +138,7 @@ public class IResourceStoreExtensionsTests
|
|||
}
|
||||
};
|
||||
|
||||
var result = await store.FindResourcesByScopeAsync(new string[] { "a" });
|
||||
var result = await store.FindResourcesByScopeAsync(new string[] { "a" }, _ct);
|
||||
result.ApiResources.Count.ShouldBe(1);
|
||||
}
|
||||
|
||||
|
|
@ -146,7 +148,7 @@ public class IResourceStoreExtensionsTests
|
|||
public List<ApiResource> ApiResources { get; set; } = new List<ApiResource>();
|
||||
public List<ApiScope> ApiScopes { get; set; } = new List<ApiScope>();
|
||||
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> names)
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> names, CT ct)
|
||||
{
|
||||
var apis = from a in ApiResources
|
||||
where names.Contains(a.Name)
|
||||
|
|
@ -154,7 +156,7 @@ public class IResourceStoreExtensionsTests
|
|||
return Task.FromResult(apis);
|
||||
}
|
||||
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> names)
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> names, CT ct)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(names);
|
||||
|
||||
|
|
@ -165,7 +167,7 @@ public class IResourceStoreExtensionsTests
|
|||
return Task.FromResult(api);
|
||||
}
|
||||
|
||||
public Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> names)
|
||||
public Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> names, CT ct)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(names);
|
||||
|
||||
|
|
@ -176,7 +178,7 @@ public class IResourceStoreExtensionsTests
|
|||
return Task.FromResult(identity);
|
||||
}
|
||||
|
||||
public Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames)
|
||||
public Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames, CT ct)
|
||||
{
|
||||
var q = from x in ApiScopes
|
||||
where scopeNames.Contains(x.Name)
|
||||
|
|
@ -184,7 +186,7 @@ public class IResourceStoreExtensionsTests
|
|||
return Task.FromResult(q);
|
||||
}
|
||||
|
||||
public Task<Resources> GetAllResourcesAsync()
|
||||
public Task<Resources> GetAllResourcesAsync(CT ct)
|
||||
{
|
||||
var result = new Resources(IdentityResources, ApiResources, ApiScopes);
|
||||
return Task.FromResult(result);
|
||||
|
|
|
|||
|
|
@ -22,15 +22,15 @@ public class IdentityServerBuilderExtensionsCacheStoreTests
|
|||
|
||||
private class CustomResourceStore : IResourceStore
|
||||
{
|
||||
public Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames) => throw new System.NotImplementedException();
|
||||
public Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames, CT ct) => throw new System.NotImplementedException();
|
||||
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames) => throw new System.NotImplementedException();
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames, CT ct) => throw new System.NotImplementedException();
|
||||
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> names) => throw new System.NotImplementedException();
|
||||
public Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> names, CT ct) => throw new System.NotImplementedException();
|
||||
|
||||
public Task<Resources> GetAllResourcesAsync() => throw new System.NotImplementedException();
|
||||
public Task<Resources> GetAllResourcesAsync(CT ct) => throw new System.NotImplementedException();
|
||||
|
||||
public Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames) => throw new System.NotImplementedException();
|
||||
public Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames, CT ct) => throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ namespace UnitTests.Stores.Default;
|
|||
|
||||
public class CachingResourceStoreTests
|
||||
{
|
||||
private readonly CT _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
private List<IdentityResource> _identityResources = new List<IdentityResource>();
|
||||
private List<ApiResource> _apiResources = new List<ApiResource>();
|
||||
private List<ApiScope> _apiScopes = new List<ApiScope>();
|
||||
|
|
@ -48,7 +50,7 @@ public class CachingResourceStoreTests
|
|||
|
||||
_scopeCache.Items.Count.ShouldBe(0);
|
||||
|
||||
var items = await _subject.FindApiScopesByNameAsync(new[] { "scope3", "scope1", "scope2", "invalid" });
|
||||
var items = await _subject.FindApiScopesByNameAsync(new[] { "scope3", "scope1", "scope2", "invalid" }, _ct);
|
||||
items.Count().ShouldBe(3);
|
||||
|
||||
_scopeCache.Items.Count.ShouldBe(3);
|
||||
|
|
@ -64,23 +66,23 @@ public class CachingResourceStoreTests
|
|||
|
||||
_scopeCache.Items.Count.ShouldBe(0);
|
||||
|
||||
var items = await _subject.FindApiScopesByNameAsync(new[] { "scope1" });
|
||||
var items = await _subject.FindApiScopesByNameAsync(new[] { "scope1" }, _ct);
|
||||
items.Count().ShouldBe(1);
|
||||
_scopeCache.Items.Count.ShouldBe(1);
|
||||
|
||||
_apiScopes.Remove(_apiScopes.Single(x => x.Name == "scope1"));
|
||||
items = await _subject.FindApiScopesByNameAsync(new[] { "scope1", "scope2" });
|
||||
items = await _subject.FindApiScopesByNameAsync(new[] { "scope1", "scope2" }, _ct);
|
||||
items.Count().ShouldBe(2);
|
||||
_scopeCache.Items.Count.ShouldBe(2);
|
||||
|
||||
_apiScopes.Remove(_apiScopes.Single(x => x.Name == "scope2"));
|
||||
items = await _subject.FindApiScopesByNameAsync(new[] { "scope3", "scope2", "scope4" });
|
||||
items = await _subject.FindApiScopesByNameAsync(new[] { "scope3", "scope2", "scope4" }, _ct);
|
||||
items.Count().ShouldBe(3);
|
||||
_scopeCache.Items.Count.ShouldBe(4);
|
||||
|
||||
// this shows we will find it in the cache, even if removed from the DB
|
||||
_apiScopes.Remove(_apiScopes.Single(x => x.Name == "scope3"));
|
||||
items = await _subject.FindApiScopesByNameAsync(new[] { "scope3", "scope1", "scope2" });
|
||||
items = await _subject.FindApiScopesByNameAsync(new[] { "scope3", "scope1", "scope2" }, _ct);
|
||||
items.Count().ShouldBe(3);
|
||||
_scopeCache.Items.Count.ShouldBe(4);
|
||||
}
|
||||
|
|
@ -98,7 +100,7 @@ public class CachingResourceStoreTests
|
|||
{
|
||||
_apiCache.Items.Count.ShouldBe(0);
|
||||
_apiResourceNamesCache.Items.Count.ShouldBe(0);
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "invalid" });
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "invalid" }, _ct);
|
||||
items.Count().ShouldBe(0);
|
||||
_apiCache.Items.Count.ShouldBe(0);
|
||||
_apiResourceNamesCache.Items.Count.ShouldBe(1);
|
||||
|
|
@ -111,7 +113,7 @@ public class CachingResourceStoreTests
|
|||
|
||||
_apiCache.Items.Count.ShouldBe(0);
|
||||
_apiResourceNamesCache.Items.Count.ShouldBe(0);
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo1" });
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo1" }, _ct);
|
||||
items.Count().ShouldBe(1);
|
||||
items.Select(x => x.Name).ShouldBe(new[] { "foo" });
|
||||
_apiCache.Items.Count.ShouldBe(1);
|
||||
|
|
@ -119,7 +121,7 @@ public class CachingResourceStoreTests
|
|||
}
|
||||
|
||||
{
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo2" });
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo2" }, _ct);
|
||||
items.Count().ShouldBe(1);
|
||||
items.Select(x => x.Name).ShouldBe(["foo"]);
|
||||
_apiCache.Items.Count.ShouldBe(1);
|
||||
|
|
@ -127,7 +129,7 @@ public class CachingResourceStoreTests
|
|||
}
|
||||
|
||||
{
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo1", "bar1" });
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo1", "bar1" }, _ct);
|
||||
items.Count().ShouldBe(2);
|
||||
items.Select(x => x.Name).ShouldBe(["foo", "bar"]);
|
||||
_apiCache.Items.Count.ShouldBe(2);
|
||||
|
|
@ -135,7 +137,7 @@ public class CachingResourceStoreTests
|
|||
}
|
||||
|
||||
{
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo2", "foo1", "bar2", "bar1" });
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo2", "foo1", "bar2", "bar1" }, _ct);
|
||||
items.Count().ShouldBe(2);
|
||||
items.Select(x => x.Name).ShouldBe(["foo", "bar"]);
|
||||
_apiCache.Items.Count.ShouldBe(2);
|
||||
|
|
@ -147,7 +149,7 @@ public class CachingResourceStoreTests
|
|||
_apiResourceNamesCache.Items.Clear();
|
||||
_resourceCache.Items.Clear();
|
||||
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo2", "foo1", "bar2", "bar1" });
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo2", "foo1", "bar2", "bar1" }, _ct);
|
||||
items.Count().ShouldBe(2);
|
||||
items.Select(x => x.Name).ShouldBe(["foo", "bar"]);
|
||||
_apiCache.Items.Count.ShouldBe(2);
|
||||
|
|
@ -160,7 +162,7 @@ public class CachingResourceStoreTests
|
|||
_apiScopes.Clear();
|
||||
_identityResources.Clear();
|
||||
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo2", "foo1", "bar2", "bar1" });
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo2", "foo1", "bar2", "bar1" }, _ct);
|
||||
items.Count().ShouldBe(2);
|
||||
items.Select(x => x.Name).ShouldBe(["foo", "bar"]);
|
||||
_apiCache.Items.Count.ShouldBe(2);
|
||||
|
|
@ -179,12 +181,12 @@ public class CachingResourceStoreTests
|
|||
_apiScopes.Add(new ApiScope("bar1"));
|
||||
|
||||
{
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo", "foo1", "bar", "bar1" });
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo", "foo1", "bar", "bar1" }, _ct);
|
||||
items.Count().ShouldBe(2);
|
||||
items.Select(x => x.Name).ShouldBe(["foo", "bar"], true);
|
||||
}
|
||||
{
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo", "foo1", "bar", "bar1" });
|
||||
var items = await _subject.FindApiResourcesByScopeNameAsync(new[] { "foo", "foo1", "bar", "bar1" }, _ct);
|
||||
items.Count().ShouldBe(2);
|
||||
items.Select(x => x.Name).ShouldBe(["foo", "bar"]);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue