diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Devices/DeviceFlowStore.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Devices/DeviceFlowStore.cs new file mode 100644 index 0000000000..bfc5e62f7c --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Devices/DeviceFlowStore.cs @@ -0,0 +1,98 @@ +using System; +using System.IdentityModel.Tokens.Jwt; +using System.Threading.Tasks; +using IdentityModel; +using IdentityServer4.Models; +using IdentityServer4.Stores; +using IdentityServer4.Stores.Serialization; +using JetBrains.Annotations; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Guids; + +namespace Volo.Abp.IdentityServer.Devices +{ + public class DeviceFlowStore : IDeviceFlowStore, ITransientDependency + { + protected IDeviceFlowCodesRepository DeviceFlowCodesRepository { get; } + protected IGuidGenerator GuidGenerator { get; } + protected IPersistentGrantSerializer PersistentGrantSerializer { get; } + + public DeviceFlowStore( + IDeviceFlowCodesRepository deviceFlowCodesRepository, + IGuidGenerator guidGenerator, + IPersistentGrantSerializer persistentGrantSerializer) + { + DeviceFlowCodesRepository = deviceFlowCodesRepository; + GuidGenerator = guidGenerator; + PersistentGrantSerializer = persistentGrantSerializer; + } + + public async Task StoreDeviceAuthorizationAsync(string deviceCode, string userCode, DeviceCode data) + { + Check.NotNull(deviceCode, nameof(deviceCode)); + Check.NotNull(userCode, nameof(userCode)); + Check.NotNull(data, nameof(data)); + + await DeviceFlowCodesRepository.InsertAsync( + new DeviceFlowCodes(GuidGenerator.Create()) + { + DeviceCode = deviceCode, + UserCode = userCode, + ClientId = data.ClientId, + SubjectId = data.Subject?.FindFirst(JwtClaimTypes.Subject).Value, + CreationTime = data.CreationTime, + Expiration = data.CreationTime.AddSeconds(data.Lifetime), + Data = Serialize(data) + } + ).ConfigureAwait(false); + } + + public async Task FindByUserCodeAsync(string userCode) + { + Check.NotNull(userCode, nameof(userCode)); + + var deviceCodes = await DeviceFlowCodesRepository.FindByUserCodeAsync(userCode).ConfigureAwait(false); + if (deviceCodes == null) + { + return null; + } + + return DeserializeToDeviceCode(deviceCodes.Data); + } + + public Task FindByDeviceCodeAsync(string deviceCode) + { + throw new NotImplementedException(); + } + + public Task UpdateByUserCodeAsync(string userCode, DeviceCode data) + { + throw new NotImplementedException(); + } + + public Task RemoveByDeviceCodeAsync(string deviceCode) + { + throw new NotImplementedException(); + } + + private string Serialize([CanBeNull] DeviceCode deviceCode) + { + if (deviceCode == null) + { + return null; + } + + return PersistentGrantSerializer.Serialize(deviceCode); + } + + protected virtual DeviceCode DeserializeToDeviceCode([CanBeNull] string data) + { + if (data == null) + { + return null; + } + + return PersistentGrantSerializer.Deserialize(data); + } + } +} diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Devices/IDeviceFlowCodesRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Devices/IDeviceFlowCodesRepository.cs index 7dbbcaff69..f40f8f0353 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Devices/IDeviceFlowCodesRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Devices/IDeviceFlowCodesRepository.cs @@ -1,10 +1,15 @@ using System; +using System.Threading; +using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; namespace Volo.Abp.IdentityServer.Devices { public interface IDeviceFlowCodesRepository : IBasicRepository { - + Task FindByUserCodeAsync( + string userCode, + CancellationToken cancellationToken = default + ); } } diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/Devices/DeviceFlowCodesRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/Devices/DeviceFlowCodesRepository.cs index f8882d743d..c722d3b99a 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/Devices/DeviceFlowCodesRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/Devices/DeviceFlowCodesRepository.cs @@ -1,4 +1,7 @@ using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.IdentityServer.EntityFrameworkCore; @@ -13,5 +16,14 @@ namespace Volo.Abp.IdentityServer.Devices { } + + public async Task FindByUserCodeAsync( + string userCode, + CancellationToken cancellationToken = default) + { + return await DbSet + .FirstOrDefaultAsync(d => d.UserCode == userCode, GetCancellationToken(cancellationToken)) + .ConfigureAwait(false); + } } } diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/Grants/PersistedGrantRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/Grants/PersistedGrantRepository.cs index e0af04c53e..ca404c84e5 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/Grants/PersistedGrantRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/Grants/PersistedGrantRepository.cs @@ -12,7 +12,8 @@ namespace Volo.Abp.IdentityServer.Grants { public class PersistentGrantRepository : EfCoreRepository, IPersistentGrantRepository { - public PersistentGrantRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + public PersistentGrantRepository(IDbContextProvider dbContextProvider) + : base(dbContextProvider) { } diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoDeviceFlowCodesRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoDeviceFlowCodesRepository.cs index 6589376e52..8357c116f4 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoDeviceFlowCodesRepository.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoDeviceFlowCodesRepository.cs @@ -1,4 +1,7 @@ using System; +using System.Threading; +using System.Threading.Tasks; +using MongoDB.Driver.Linq; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.IdentityServer.Devices; using Volo.Abp.MongoDB; @@ -11,6 +14,16 @@ namespace Volo.Abp.IdentityServer.MongoDB public MongoDeviceFlowCodesRepository( IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) { + + } + + public async Task FindByUserCodeAsync( + string userCode, + CancellationToken cancellationToken = default) + { + return await GetMongoQueryable() + .FirstOrDefaultAsync(d => d.UserCode == userCode, GetCancellationToken(cancellationToken)) + .ConfigureAwait(false); } } } \ No newline at end of file