Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature(oidc):add Oidc.EntityFramework、Oidc.Cache.Storage #78

Merged
merged 32 commits into from
Jun 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4fda278
add oidc project
wuweilaiya May 23, 2022
dd4e1e1
Merge branch 'main' into feature/oidc
wuweilaiya Jun 6, 2022
033600c
feat(oidc):oidc
wuweilaiya Jun 7, 2022
d00b725
feat(oidc):oidc
wuweilaiya Jun 7, 2022
f54bcd4
feat(oidc):oidc
wuweilaiya Jun 8, 2022
e2bc8c5
feat(oidc):oidc
wuweilaiya Jun 8, 2022
83c11d7
feat(oidc):oidc
wuweilaiya Jun 9, 2022
758ba50
feat(oidc):oidc
wuweilaiya Jun 9, 2022
a57b958
feat(oidc):oidc
wuweilaiya Jun 9, 2022
134fe74
feat(oidc):oidc
wuweilaiya Jun 9, 2022
e369dff
feat:add redis cache options
Jun 9, 2022
2e167c8
feat(oidc):oidc
wuweilaiya Jun 9, 2022
229433d
feat(oidc):oidc
wuweilaiya Jun 10, 2022
28b0c63
feat(oidc):oidc
wuweilaiya Jun 10, 2022
59409f6
feat:update cache
Jun 10, 2022
13a9527
feat(oidc):oidc
wuweilaiya Jun 13, 2022
85b2c5d
feat(oidc)Loidc
wuweilaiya Jun 13, 2022
d643718
feat(oidc):oidc
wuweilaiya Jun 13, 2022
eaae717
feat(oidc):oidc
wuweilaiya Jun 13, 2022
79f4aec
refactor:formatting code
wuweilaiya Jun 13, 2022
c5f25b6
merge:merges the latest code in the main branch
wuweilaiya Jun 13, 2022
0d5488c
feat(oidc):remove AddAllAsync,add ResetAsync
wuweilaiya Jun 14, 2022
05dcc39
refactor(code):refactor code
wuweilaiya Jun 14, 2022
e6436b2
refactor:refactor code
wuweilaiya Jun 15, 2022
295ff2f
refactor:refactor code
wuweilaiya Jun 15, 2022
5d9f409
merge:Merges the latest code in the main branch
wuweilaiya Jun 15, 2022
0d86a64
refactor:refactor code
wuweilaiya Jun 15, 2022
565f6c2
refactor(code):refactor code
wuweilaiya Jun 20, 2022
c3fb064
merge:merges the latest code in the main branch
wuweilaiya Jun 20, 2022
18802ac
merge:merges the latest code in the main branch
wuweilaiya Jun 21, 2022
e9dba90
merge:merges the latest code in the main branch
wuweilaiya Jun 21, 2022
c76fa31
merge:merges the latest code in the main branch
wuweilaiya Jun 21, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 120 additions & 47 deletions Masa.Contrib.sln

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<WarningsAsErrors>
$(WarningsAsErrors);CS8600;CS8601;CS8602;CS8603;CS8604;CS8609;CS8610;CS8614;CS8616;CS8618;CS8619;CS8620;CS8622;CS8625
</WarningsAsErrors>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Masa.Utils.Caching.DistributedMemory" Version="$(MasaUtilsPackageVersion)" />
<PackageReference Include="Masa.Utils.Caching.Redis" Version="$(MasaUtilsPackageVersion)" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\BuildingBlocks\MASA.BuildingBlocks\src\Authentication\Masa.BuildingBlocks.Authentication.Oidc.Storage\Masa.BuildingBlocks.Authentication.Oidc.Storage.csproj" />
<ProjectReference Include="..\Masa.Contrib.Authentication.Oidc.Cache\Masa.Contrib.Authentication.Oidc.Cache.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Contrib.Authentication.Oidc.Cache.Storage;

public static class ServiceCollectionExtensions
{
public static IServiceCollection AddOidcCacheStorage(this IServiceCollection services, RedisConfigurationOptions options)
{
services.AddOidcCache(options);
services.AddSingleton<IClientStore, ClientStore>();
services.AddSingleton<IResourceStore, ResourceStore>();
services.AddSingleton<IPersistedGrantStore, PersistedGrantStore>();
services.AddSingleton<IDeviceFlowStore, DeviceFlowStore>();

return services;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Contrib.Authentication.Oidc.Cache.Storage.Stores;

public class ClientStore : IClientStore
{
IClientCache _clientCache;

public ClientStore(IClientCache clientCache)
{
_clientCache = clientCache;
}

public async Task<ClientModel?> FindClientByIdAsync(string clientId)
{
ArgumentNullException.ThrowIfNull(clientId);

var client = await _clientCache.GetAsync(clientId);
return client;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Contrib.Authentication.Oidc.Cache.Storage.Stores;

public class DeviceFlowStore : IDeviceFlowStore
{
public Task<DeviceCodeModel> FindByDeviceCodeAsync(string deviceCode)
{
throw new NotImplementedException();
}

public Task<DeviceCodeModel> FindByUserCodeAsync(string userCode)
{
throw new NotImplementedException();
}

public Task RemoveByDeviceCodeAsync(string deviceCode)
{
throw new NotImplementedException();
}

public Task StoreDeviceAuthorizationAsync(string deviceCode, string userCode, DeviceCodeModel data)
{
throw new NotImplementedException();
}

public Task UpdateByUserCodeAsync(string userCode, DeviceCodeModel data)
{
throw new NotImplementedException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Contrib.Authentication.Oidc.Cache.Storage.Stores;

public class PersistedGrantStore : IPersistedGrantStore
{
public Task<IEnumerable<PersistedGrantModel>> GetAllAsync(PersistedGrantFilter filter)
{
throw new NotImplementedException();
}

public Task<PersistedGrantModel> GetAsync(string key)
{
throw new NotImplementedException();
}

public Task RemoveAllAsync(PersistedGrantFilter filter)
{
throw new NotImplementedException();
}

public Task RemoveAsync(string key)
{
throw new NotImplementedException();
}

public Task StoreAsync(PersistedGrantModel grant)
{
throw new NotImplementedException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Contrib.Authentication.Oidc.Cache.Storage.Stores;

public class ResourceStore : IResourceStore
{
IIdentityResourceCache _identityResourceCache;
IApiResourceCache _apiResourceCache;
IApiScopeCache _apiScopeCache;

public ResourceStore(IIdentityResourceCache identityResourceCache, IApiResourceCache apiResourceCache, IApiScopeCache apiScopeCache)
{
_identityResourceCache = identityResourceCache;
_apiResourceCache = apiResourceCache;
_apiScopeCache = apiScopeCache;
}

public async Task<IEnumerable<ApiResourceModel>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames)
{
ArgumentNullException.ThrowIfNull(apiResourceNames);

return await _apiResourceCache.GetListAsync(apiResourceNames);
}

public async Task<IEnumerable<ApiResourceModel>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames)
{
ArgumentNullException.ThrowIfNull(scopeNames);

var apiResources = await _apiResourceCache.GetListAsync();
return apiResources.Where(apiResource => apiResource.Scopes?.Any(scope => scopeNames.Contains(scope)) is true);
}

public async Task<IEnumerable<ApiScopeModel>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames)
{
ArgumentNullException.ThrowIfNull(scopeNames);

var apiScopes = await _apiScopeCache.GetListAsync(scopeNames);
return apiScopes;
}

public async Task<IEnumerable<IdentityResourceModel>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames)
{
ArgumentNullException.ThrowIfNull(scopeNames);

var identityResources = await _identityResourceCache.GetListAsync(scopeNames);
return identityResources;
}

public async Task<ResourcesModel> GetAllResourcesAsync()
{
var identityResources = await _identityResourceCache.GetListAsync();
var apiScopes = await _apiScopeCache.GetListAsync();
var apiResources = await _apiResourceCache.GetListAsync();
var resources = new ResourcesModel(identityResources, apiResources, apiScopes);
return resources;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

global using Masa.BuildingBlocks.Authentication.Oidc.Cache.Caches;
global using Masa.BuildingBlocks.Authentication.Oidc.Models.Models;
global using Masa.BuildingBlocks.Authentication.Oidc.Storage.Stores;
global using Masa.Contrib.Authentication.Oidc.Cache.Storage.Stores;
global using Microsoft.Extensions.DependencyInjection;
global using Masa.Utils.Caching.Redis.Models;
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Contrib.Authentication.Oidc.Cache.Caches;

public class ApiResourceCache : IApiResourceCache
{
IMemoryCacheClient _memoryCacheClient;

public ApiResourceCache(IMemoryCacheClient memoryCacheClient)
{
_memoryCacheClient = memoryCacheClient;
}

public async Task<List<ApiResourceModel>> GetListAsync(IEnumerable<string> names)
{
var keys = names.Select(name => $"{CacheKeyConstants.API_RESOURCE_KEY}_{name}");
var apiResources = await _memoryCacheClient.GetListAsync<ApiResourceModel>(keys.ToArray());
return apiResources.Where(i => i is not null).ToList()!;
}

public async Task<List<ApiResourceModel>> GetListAsync()
{
var apiResources = await _memoryCacheClient.GetAsync<List<ApiResourceModel>>(CacheKeyConstants.API_RESOURCE_KEY) ?? new();
return apiResources;
}

public async Task SetAsync(ApiResource apiResource)
{
var model = apiResource.ToModel();
string key = $"{CacheKeyConstants.API_RESOURCE_KEY}_{apiResource.Name}";
await _memoryCacheClient.SetAsync(key, model);
// update list cache
var list = await GetListAsync();
list.Set(model, item => item.Name);
await UpdateListAsync(list);
}

public async Task SetRangeAsync(IEnumerable<ApiResource> apiResources)
{
var models = apiResources.Select(apiScope => apiScope.ToModel());
var map = models.ToDictionary(model => $"{CacheKeyConstants.API_RESOURCE_KEY}_{model.Name}", model => model);
await _memoryCacheClient.SetListAsync(map);
// update list cache
var list = await GetListAsync();
list.SetRange(models, item => item.Name);
await UpdateListAsync(list);
}

public async Task RemoveAsync(ApiResource apiResource)
{
string key = $"{CacheKeyConstants.API_RESOURCE_KEY}_{apiResource.Name}";
await _memoryCacheClient.RemoveAsync<ApiResourceModel>(key);
// update list cache
var list = await GetListAsync();
list.Remove(item => item.Name == apiResource.Name);
await UpdateListAsync(list);
}

public async Task ResetAsync(IEnumerable<ApiResource> apiResources)
{
var models = apiResources.Select(apiScope => apiScope.ToModel());
await UpdateListAsync(models);
var map = models.ToDictionary(model => $"{CacheKeyConstants.API_RESOURCE_KEY}_{model.Name}", model => model);
await _memoryCacheClient.SetListAsync(map);
}

private async Task UpdateListAsync(IEnumerable<ApiResourceModel> models)
{
await _memoryCacheClient.SetAsync(CacheKeyConstants.API_RESOURCE_KEY, models);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Contrib.Authentication.Oidc.Cache.Caches;

public class ApiScopeCache : IApiScopeCache
{
IMemoryCacheClient _memoryCacheClient;

public ApiScopeCache(IMemoryCacheClient memoryCacheClient)
{
_memoryCacheClient = memoryCacheClient;
}

public async Task<List<ApiScopeModel>> GetListAsync(IEnumerable<string> names)
{
var keys = names.Select(name => $"{CacheKeyConstants.API_SCOPE_KEY}_{name}");
var apiScopes = await _memoryCacheClient.GetListAsync<ApiScopeModel>(keys.ToArray());
return apiScopes.Where(i => i is not null).ToList()!;
}

public async Task<List<ApiScopeModel>> GetListAsync()
{
var ApiScopes = await _memoryCacheClient.GetAsync<List<ApiScopeModel>>(CacheKeyConstants.API_SCOPE_KEY) ?? new();
return ApiScopes;
}

public async Task SetAsync(ApiScope apiScope)
{
string key = $"{CacheKeyConstants.API_SCOPE_KEY}_{apiScope.Name}";
var model = apiScope.ToModel();
await _memoryCacheClient.SetAsync(key, model);
// update list cache
var list = await GetListAsync();
list.Set(model, item => item.Name);
await UpdateListAsync(list);
}

public async Task SetRangeAsync(IEnumerable<ApiScope> apiScopes)
{
var models = apiScopes.Select(apiScope => apiScope.ToModel());
var data = models.ToDictionary(model => $"{CacheKeyConstants.API_SCOPE_KEY}_{model.Name}", model => model);
await _memoryCacheClient.SetListAsync(data);
// update list cache
var list = await GetListAsync();
list.SetRange(models, item => item.Name);
await UpdateListAsync(list);
}

public async Task RemoveAsync(ApiScope apiScope)
{
string key = $"{CacheKeyConstants.API_SCOPE_KEY}_{apiScope.Name}";
await _memoryCacheClient.RemoveAsync<ApiScopeModel>(key);
// update list cache
var list = await GetListAsync();
list.Remove(item => item.Name == apiScope.Name);
await UpdateListAsync(list);
}

public async Task ResetAsync(IEnumerable<ApiScope> apiScopes)
{
var models = apiScopes.Select(apiScope => apiScope.ToModel());
await UpdateListAsync(models);
var map = models.ToDictionary(model => $"{CacheKeyConstants.API_SCOPE_KEY}_{model.Name}", model => model);
await _memoryCacheClient.SetListAsync(map);
}

private async Task UpdateListAsync(IEnumerable<ApiScopeModel> models)
{
await _memoryCacheClient.SetAsync(CacheKeyConstants.API_SCOPE_KEY, models);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Contrib.Authentication.Oidc.Cache.Caches;

public class ClientCache : IClientCache
{
IMemoryCacheClient _memoryCacheClient;

public ClientCache(IMemoryCacheClient memoryCacheClient)
{
_memoryCacheClient = memoryCacheClient;
}

public async Task<ClientModel?> GetAsync(string clientId)
{
string key = $"{CacheKeyConstants.CLIENT_KEY}_{clientId}";
return await _memoryCacheClient.GetAsync<ClientModel>(key);
}

public async Task SetAsync(Client client)
{
string key = $"{CacheKeyConstants.CLIENT_KEY}_{client.ClientId}";
await _memoryCacheClient.SetAsync(key, client.ToModel());
}

public async Task RemoveAsync(Client client)
{
string key = $"{CacheKeyConstants.CLIENT_KEY}_{client.ClientId}";
await _memoryCacheClient.RemoveAsync<ClientModel>(key);
}

public async Task SetRangeAsync(IEnumerable<Client> clients)
{
var data = clients.ToDictionary(client => $"{CacheKeyConstants.CLIENT_KEY}_{client.ClientId}", client => client.ToModel());
await _memoryCacheClient.SetListAsync(data);
}
}
Loading